稀疏矩阵转置 c语言,【数据结构之旅】稀疏矩阵的快速转置

说明:

稀疏矩阵的快速转置算法的核心在于,用一个数组num记录原来矩阵中的每列非零元个数,用另一个数组cpos来记录原矩阵每列第一个非零元在新矩阵中的位置,以此来达到快速转置的目的。

用这样的方法,主要是希望,矩阵转置后,存储顺序依然是按照行来存储的。

1.实现及代码注释

根据上面的核心提示,可以有如下的代码,下面的代码中的注释已经非常详细,因此这里就不把每一部分实现的功能独立开来了:#include

#include

#define OVERFLOW -1

#define OK 1

#define ERROR 0

#define TRUE 2

#define FALSE -2

typedef int ElemType;

typedef int Status;

typedef struct{ //非零元三元组类型结构体

int i, j;//非零元的行和列

ElemType e;//非零元的值

} Triple;//非零元三元组类型结构体定义关键字

typedef struct{//矩阵类型结构体

Triple *data;//data域,指向非零元三元组的结构体指针

int mu, nu, tu;//矩阵的行数、列数和非零元个数

} TSMatrix;//矩阵类型结构体定义关键字

/*

01400-5

0-7000

3600280

mu = 3; nu = 5; tu = 5

*/

Status CreateSMatrix(TSMatrix &M){//创建一个稀疏矩阵

M.tu = 5;

M.data = (Triple*)malloc(sizeof(Triple) * (M.tu + 1)); //data域存储元素的大小比稀疏矩阵的非零元个数大1,是因为data[0]不使用

if(NULL == M.data)

return OVERFLOW;

M.data[1].i = 1;

M.data[1].j = 2;

M.data[1].e = 14;

M.data[2].i = 1;

M.data[2].j = 5;

M.data[2].e = -5;

M.data[3].i = 2;

M.data[3].j = 2;

M.data[3].e = -7;

M.data[4].i = 3;

M.data[4].j = 1;

M.data[4].e = 36;

M.data[5].i = 3;

M.data[5].j = 4;

M.data[5].e = 28;

M.mu = 3;

M.nu = 5;

return OK;

}

Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){ //采用顺序表存储表示,求稀疏矩阵M的转置矩阵T

int j, p, q, t;

/*j记录遍历时的当前列,cops[j],则表示当前列第一个非零元的位置或者该列非零元位置的其它位置(cops[j]++),正式转置时用;

p记录遍历时的非零元个数,正式转置时用;

q记录cops[j],简化代码的表示,正式转置时用 ;

t用在转置准备时。

*/

int *num;//保存每一列的非零元个数

int *cpos;//保存转置后每列第一个非零元在T中所处的序号

//cops[j]++则是该列的下一个非零元,如果存在的话

T.mu = M.nu; T.nu = M.mu; T.tu = M.tu;//初始化矩阵T

T.data = (Triple*)malloc(sizeof(Triple)*(T.nu + 1));

num = (int*)malloc((M.nu + 1)*sizeof(int));//num和cpos开辟空间比非零元个数大1,是因为不使用0号位置

cpos = (int*)malloc((M.nu + 1)*sizeof(int));

if(num == NULL || cpos == NULL)

return OVERFLOW;

if(T.tu != 0){

for(j = 1; j <= M.nu; j++)//初始化num向量

num[j] = 0;

for(t = 1;t <= M.tu; t++)//求M中每一列所含非零元的个数

num[M.data[t].j]++;//这里要用到num[1]~num[5],所以上面num要全部初始化为0

cpos[1] = 1;//这里是一定的

for(j = 2;j <= M.nu; j++)//求每列的第一个非零元在T.data中的序号

cpos[j] = cpos[j-1] + num[j-1];//画表分析得出该公式并不难

for(p = 1; p <= M.tu; p++){//上面是准备工作,下面开始正式转置

j = M.data[p].j;//j的作用是记录当前遍历的列,以让cops使用

q = cpos[j];//是为了简化代码,因为下面都要用到cpos[j]

T.data[q].i = M.data[p].j;//交换行

T.data[q].j = M.data[p].i;//交换列

T.data[q].e = M.data[p].e;//赋值 ,无论如何交换,储存顺序是已经定下来的了

cpos[j]++;//cops[j]++则是该列的下一个非零元,如果存在的话,不存在的话也没有影响

}//因为在这个for循环中,如果列变了,即j变化了,cpos[j]也不是原来的值了

}

free(num);

free(cpos);

return OK;

}

int main(void){

int i,j;

TSMatrix M;

TSMatrix T;

CreateSMatrix(M);

FastTransposeSMatrix(M, T);

printf("\n");

return 0;

}

可以用C free等编译器进行编译运行,但由于时间关系,上面的代码中并没有给出转置后的矩阵打印的代码,可以自己加上去,当然也可以通过调试的方法监视新矩阵T中的data域的数值变化。

2.测试

测试就是按照上面的提示去做就可以了,时间关系,这里就先不做测试,改天有时间再补上吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值