一.问题分析
一个稀疏矩阵M用三元组表示,设计高效率的算法将矩阵M转置后得到矩阵N
二.思路分析
1.我们先对矩阵M的顺序表进行遍历,用数组num[]记录M矩阵每一列非零元素分别有多少个,这也就是逆矩阵N每一行的非零元素有多少个.
2.利用逆矩阵N每一行的非零元素有多少个这个信息,我们就可以求出逆N矩阵中每一行非零元素在顺序表中的位置序号,每一行首非零元素在顺序表中的位置序号是上一行首非零元素的位置序号加上上一行元素的数量.我们用数组cpot[]记录.即 cpot[row]=cpot[row-1]+num[row-1];
3.我们再一次遍历矩阵M中的元素,当我们遍历到一个元素时,利用元素在M中的列号和copt存储的逆矩阵N中每行非零元的位置序号,就能求得转置元素在逆矩阵N顺序表中的序号,它在逆矩N阵顺序表中的位置就是pos=cpot[元素在M中的列号]++;注意使用后位置序号要加1,这是下次存放同一行的元素位置.有了位置序号,就将转置元素存入顺序表的该序号位置中.这样一次遍历顺序表M,就完成了转置.
三.代码实现
//线性表0单元不用是为了便于理解算法
//元素类型
typedef int ElemType;
typedef struct
{
int i; //行
int j; //列
ElemType e; //元素
}Triple; //三元组
typedef struct
{
int mu,nu,tu; //矩阵的行数,列数,非零元素的数量
Triple data[MAXSIZE+1]; //非零单元三元组表,data[0]未用
}TSMatrix; //稀疏矩阵(三元组压缩表示)
//矩阵快速转置算法
TSMatrix FastTransposeSmatrix(TSMatrix M)
{
int m=M.mu; //原矩阵行数
int n=M.nu; //原矩阵列数
int t=M.tu; //原矩阵非零元素个数
int num[m+1]={0}; //每行元素数量,零元位置不用
int row; //行
for(int i=1;i<=t;i++) //遍历顺序表中的所有元素
{
row=M.data[i].j; //遍历到的元素的列
num[row]++; //求出转置后每行元素的数量
}
int cpot[m+1]; //每行元素第一个的位置,零元位置不用
cpot[1]=1; //第一行第一个元素的位置是1
//利用上面求到的转置后每行元素的数量求出每行第一个元素在顺序表中的位置
for(row=2;row<=n;row++)
{
cpot[row]=cpot[row-1]+num[row-1]; //每行首非零元素在顺序表中的位置序号是上一行首非零元素的位置序号加上上一行元素的数量.
}
TSMatrix T; //转置后的矩阵
for(int k=1;k<=t;k++) //转置后存入顺序表相应位置
{
int pos=cpot[M.data[k].j]++; //相应位置放入元素后要往后移,这样是原矩阵同列下一个元素的位置
T.data[pos].j=M.data[k].i; //行列交换
T.data[pos].i=M.data[k].j;
T.data[pos].e=M.data[k].e; //元素不变
}
T.mu=M.nu; //转置后矩阵行数
T.nu=M.mu; //转置后矩阵列数
T.tu=M.tu; //转置后矩阵非零元素个数
return T; //返回转置后的矩阵
}