《数据结构》实验报告
题
学
专
班
学
姓
成
稀疏矩阵运算器
目
计算机学院
院
网络工程
业
别 12 级( 4)班
号
名
绩
2014 年 06 月 22 日
稀 疏 矩 阵 运 算 器
一 . 需 求 分 析
输 入 要 求 : 稀 疏 矩 阵 的 行 、 列 和 非 零 元 素 个 数
以 及 每 个 非 零 元 素 在 矩 阵 的 位 置
以 三 元 组 格 式 存 储 稀 疏 矩 阵
输 出 要 求 : 根 据 选 项 输 出
稀 疏 矩 阵 的 转 置 、 加 法 、 减 法 、 乘 法
二 . 算 法 设 计
本 程 序 中 采 用 的 数 据 模 型 ,用 到 的 抽 象 数 据 类 型 的 定 义 ,程 序 的 主 要 算 法
流 程 及 各 模 块 之 间 的 层 次 调 用 关 系
1. 抽 象 数 据 类 型 :
基 本 操 作 :
Status CreateSMatrix(TSMatrix &M)
操 作 结 果 : 初 始 化 稀 疏 数 组
void PrintSMatrix(TSMatrix M)
初 始 条 件 : 稀 疏 数 组 M 已 经 存 在
操 作 结 果 : 打 印 矩 阵 M
Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
初 始 条 件 : 稀 疏 数 组 M 、 N 已 经 存 在
操 作 结 果 : 求 矩 阵 的 和 Q=M+N
Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
初 始 条 件 : 稀 疏 数 组 M 、 N 已 经 存 在
操 作 结 果 : 求 矩 阵 的 差 Q=M-N
Status TransposeSMatrix(TSMatrix M, TSMatrix & T)
初 始 条 件 : 稀 疏 数 组 M 已 经 存 在
操 作 结 果 : 求 矩 阵 M 的 转 置 T
Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
初 始 条 件 : 稀 疏 数 组 M 已 经 存 在
操 作 结 果 : 求 矩 阵 的 积 Q=M*N
}ADT List
2. 本 程 序 有 二 个 模 块 :
( 1) 主 程 序 模 块
main()
{
初 始 化 ;
输 出 菜 单 , 命 令 提 示 ;
{
接 受 命 令 ;
显 示 结 果 ;
}
}
( 2) 三 元 组 表 单 元 模 块 : 实 现 矩 阵 抽 象 数 据 类 型 。
三 . 程 序 设 计
根 据 算 法 设 计 中 给 出 的 有 关 数 据 和 算 法 ,选 定 物 理 结 构 ,详 细 设 计 需 求 分
析 中 所 要 求 的 程 序 。 包 括 :人 机 界 面 设 计 、 主 要 功 能 的 函 数 设 计 、 函 数 之 间
调 用 关 系 描 述 等 。
程序基本结构:
MAIN
功能选择
ADD
SUB
MUL
Trans
矩阵输出
Triple; // 定 义 三 元 组 的 元 素
TSMatrix; // 定 义 普 通 三 元 组 对 象
RLSMatrix; // 定 义 带 链 接 信 息 的 三 元 组 对 象
CrossList; //
定 义 十 字 链 表 对 象 结 构 体
2、 稀 疏 矩 阵 的 三 元 组 顺 序 表 存 储 表 示 :
typedef struct { // 定 义 三 元 组 的 元 素
int i, j;
int e;
} Triple;
typedef struct { // 定 义 普 通 三 元 组 对 象
Triple data[MAXSIZE + 1];
int mu, nu, tu;
} TSMatrix;
typedef struct { // 定 义 带 链 接 信 息 的 三 元 组 对 象
Triple data[MAXSIZE + 2];
int rpos[MAXROW + 1];
int mu, nu, tu;
} RLSMatrix;
typedef struct {
OLink *rhead, *chead;
int mu, nu, tu;
} CrossList; //定 义 十 字 链 表 对 象 结 构 体
3、 基 本 函 数 :
1) 输 入 矩 阵 , 按 三 元 组 格 式 输 入
bool InPutTSMatrix(P & T, int y) {
cout << "输 入 矩 阵 的 行 , 列 和 非 零 元 素 个 数 :" << endl;
cin >> T.mu >> T.nu >> T.tu;
cout << "请 输 出 非 零 元 素 的 位 置 和 值 :" << endl;
int k = 1;
for (; k <= T.tu; k++)
cin >> T.data[k].i >> T.data[k].j >> T.data[k].e;
return true;
}
2) 输 出 矩 阵 , 按 标 准 格 式 输 出
bool OutPutSMatrix(P T) {
int m, n, k = 1;
for (m = 0; m < T.mu; m++) {
for (n = 0; n < T.nu; n++) {
if ((T.data[k].i - 1) == m && (T.data[k].j - 1) == n) {
cout.width(4);
cout << T.data[k++].e;
} else {
cout.width(4);
cout << "0";
}
}
cout << endl;
}
return true;
}
3) 创 建 十 字 链 表
Bool CreateSMatrix_OL(CrossList & M) {
int x, y, m;
cout << "请 输 入 矩 阵 的 行 , 列 , 及 非 零 元 素 个 数 " << endl;
cin >> M.mu >> M.nu >> M.tu;
if (!(M.rhead = (OLink*) malloc((M.mu + 1) * sizeof (OLink)))) exit(0);
if (!(M.chead = (OLink*) malloc((M.nu + 1) * sizeof (OLink)))) exit(0);
for (x = 0; x <= M.mu; x++)
M.rhead[x] = NULL; // 初 始 化 各 行 , 列 头 指 针 , 分 别 为 NULL
for (x = 0; x <= M.nu; x++)
M.chead[x] = NULL;
cout << "请 按 三 元 组 的 格 式 输 入 数 组 : " << endl;
for (int i = 1; i <= M.tu; i++) {
cin >> x >> y >> m; // 按 任 意 顺 序 输 入 非 零 元 , ( 普 通 三 元 组 形 式 输 入 )
OLink p, q;
if (!(p = (OLink) malloc(sizeof (OLNode)))) exit(0); // 开 辟 新 节 点 , 用 来 存 储
输 入 的 新 元 素
p->i = x;
p->j = y;
p->e = m;
if (M.rhead[x] == NULL || M.rhead[x]->j > y) {
p->right = M.rhead[x];
M.rhead[x] = p;
} else {
for (q = M.rhead[x]; (q->right) && (q->right->j < y); q = q->right); //
查 找 节 点 在 行 表 中 的 插 入 位 置
p->right = q->right;
q->right = p; //
完 成 行 插 入
}
if (M.chead[y] == NULL || M.chead[y]->i > x) {
p->down = M.chead[y];
M.chead[y] = p;
} else {
for (q = M.chead[y]; (q->down) && (q->down->i < x); q = q->down); //
查 找 节 点 在 列 表 中 的 插 入 位 置
p->down = q->down;
q->down = p; // 完 成 列 插 入
}
}
return true;
创 建 十 字 链 表
}//
4) 按 标 准 输 出 十 字 链 表
bool OutPutSMatrix_OL(CrossList T) { // 输 出 十 字 链 表 , 用 普 通 数 组 形 式 输 出
for (int i = 1; i <= T.mu; i++) {
OLink p = T.rhead[i];
for (int j = 1; j <= T.nu; j++) {
if ((p) && (j == p->j)) {
cout << setw(3) << p->e;
p = p->right;
cout << setw(3) << "0";
} else
}
cout << endl;
}
return true;
}// 输 出 十 字 链 表
5) 求 矩 阵 的 转 置 矩 阵
bool TransposeSMatrix() {
TSMatrix M, T; // 定 义 预 转 置 的 矩 阵
InPutTSMatrix(M, 0); // 输 入 矩 阵
int num[MAXROW + 1];
int cpot[MAXROW + 1]; // 构 建 辅 助 数 组
int q, p, t;
T.tu = M.tu;
T.mu = M.nu;
T.nu = M.mu;
if (T.tu) {
for (int col = 1; col <= M.nu; col++) num[col] = 0;
for (t = 1; t <= M.tu; t++) ++num[M.data[t].j];
cpot[1] = 1;
for (int i = 2; i <= M.nu; i++) cpot[i] = cpot[i - 1] + num[i - 1];
for (p = 1; p <= M.tu; p++) {
int col = M.data[p].j;
q = cpot[col];
T.data[q].i = col;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++cpot[col];
}
}
cout << "输 入 矩 阵 的 转 置 矩 阵 为 " << endl;
OutPutSMatrix(T);
return true;
}
6) 两 个 矩 阵 相 乘
bool MultSMatrix() {
RLSMatrix M, N, Q; // 构 建 三 个 带 “ 链 接 信 息 ” 的 三 元 组 表 示 的 数 组
InPutTSMatrix(M, 1); // 用 普 通 三 元 组 形 式 输 入 数 组
InPutTSMatrix(N, 1);
Count(M);
Count(N);
if (M.nu != N.mu) return false;
Q.mu = M.mu;
Q.nu = N.nu;
Q.tu = 0; //Q 初 始 化
int ctemp[MAXROW + 1]; // 辅 助 数 组
int arow, tp, p, brow, t, q, ccol;
if (M.tu * N.tu) { //
Q 是 非 零 矩 阵
for (arow = 1; arow <= M.mu; arow++) {
///memset(ctemp,0,N.nu);
for (int x = 1; x <= N.nu; x++)
ctemp[x] = 0;
Q.rpos[arow] = Q.tu + 1; // 当 前 行 的 首 个 非 零 元 素 在 三 元 组 中 的 位 置 为
此 行 前 所 有 非 零 元 素 +1
if (arow < M.mu) tp = M.rpos[arow + 1];
else tp = M.tu + 1;
for (p = M.rpos[arow]; p < tp; p++) { //
对 当 前 行 每 个 非 零 元 素 进 行 操
brow = M.data[p].j; // 在 N 中 找 到 i 值 也 操 作 元 素 的 j 值 相 等 的 行
if (brow < N.mu) t = N.rpos[brow + 1];
else t = N.tu + 1;
for (q = N.rpos[brow]; q < t; q++) { // 对 找 出 的 行 当 每 个 非 零 元 素
作
进 行 操 作
ccol = N.data[q].j;
ctemp[ccol] += M.data[p].e * N.data[q].e; //
将 乘 得 到 对 应
值 放 在 相 应 的 元 素 累 加 器 里 面
}
}
for (ccol = 1; ccol <= Q.nu; ccol++) //
对 已 经 求 出 的 累 加 器 中 的 值 压