第五章稀疏矩阵三元组表示

合集下载

用三元组表示稀疏矩阵的乘法

用三元组表示稀疏矩阵的乘法

图5.17给出了一个矩阵相乘的例子。当矩阵M、N是稀疏 矩阵时,我们可以采用三元组表的表示形式来实现矩阵的相 乘。
3 0 0 5
0 2
1 0
M 0 1 0 0 N
2 0 0 0
2 4
0 0
0 6
Q 1 0
0 4
图5.17 Q=M×N
图5.18 矩阵M、N、Q的三元组表
{
OLink * row_head, *col_head; /* 行、 列链表的头指针向量 */
int m, n, len; /* 稀疏矩阵的行数、 列数、 非零元素的个数 */
}CrossList;
CreateCrossList (CrossList * M) {/* 采用十字链表存储结构, 创建稀疏矩阵M */ scanf(&m, &n, &t); /* 输入M的行数, 列数和非零元素的个数 */ M->m=m; M->n=n; M->len=t; If(!(M->row_head=(OLink * )malloc((m+1)sizeof(OLink)))) exit(OVERFLOW); If(!(M->col_head=(OLink * )malloc((n+1)sizeof(OLink)))) exit(OVERFLOW); M->row_head[ ]=M->col_head[ ]=NULL;
}TriSparMatrix;
具体算法如下:
该算法的时间主要耗费在乘法运算及累加上,其时间复杂度为O (A.len×B.n)。当A.len 接近于A.m×A.n时,该算法时间复杂度接近于 经典算法的时间复杂度O(A.m×A.n×B.n)。

稀疏矩阵的三元组顺序表存储表示及其转置算法

稀疏矩阵的三元组顺序表存储表示及其转置算法

稀疏矩阵的三元组顺序表存储表示及其转置算法目录1. 引言1.1 背景和意义1.2 结构概述1.3 目的2. 稀疏矩阵的三元组顺序表存储表示2.1 稀疏矩阵的定义与特点2.2 三元组顺序表的数据结构和实现方式2.3 存储表示的优缺点分析3. 稀疏矩阵转置算法3.1 转置操作的意义与应用场景3.2 基于三元组顺序表的转置算法设计思路3.3 转置算法的具体实现步骤与复杂度分析4. 实验与结果分析4.1 实验设置和数据样本介绍4.2 转置算法在不同稀疏矩阵上的性能评估和结果比较4.3 分析结果及启示与讨论5. 结论与展望5.1 结论总结5.2 存在问题及后续工作展望1. 引言1.1 背景和意义稀疏矩阵是一种在实际问题中经常遇到的特殊矩阵结构,其绝大部分元素为零。

与稠密矩阵相比,稀疏矩阵的存储和计算效率更高。

稀疏矩阵可以应用于图像处理、网络分析、线性代数等领域。

三元组顺序表是一种存储稀疏矩阵的数据结构,通过记录非零元素的行索引、列索引和数值,有效地减少了存储空间。

同时,三元组顺序表也提供了便捷的转置操作方式。

因此,深入掌握稀疏矩阵的三元组顺序表存储表示及其转置算法对于提高稀疏矩阵相关问题的解决效率具有重要意义。

1.2 结构概述本文将从两个方面进行论述。

首先,介绍稀疏矩阵的定义与特点,以及三元组顺序表在存储表示中所采用的数据结构和实现方式。

其次,详细描述了基于三元组顺序表的稀疏矩阵转置算法的设计思路、具体实现步骤和复杂度分析。

1.3 目的本文旨在探究稀疏矩阵的三元组顺序表存储表示及其转置算法,在理论层面上深入分析其原理和优劣,并在实验中验证其性能表现。

通过本文的研究,我们希望能够提供一种高效、灵活且易于实现的方法来处理稀疏矩阵,并为进一步的相关应用提供有价值的启示和参考。

2. 稀疏矩阵的三元组顺序表存储表示2.1 稀疏矩阵的定义与特点稀疏矩阵是指在一个二维矩阵中,大部分元素都为0的情况下,只有少数非零元素的情况。

三元组表示稀疏矩阵

三元组表示稀疏矩阵

三元组表示稀疏矩阵本节介绍稀疏矩阵三元序列表的压缩存储方式。

通过《矩阵的压缩存储》一节我们知道,稀疏矩阵的压缩存储,至少需要存储以下信息:•矩阵中各非 0 元素的值,以及所在矩阵中的行标和列标;•矩阵的总行数和总列数;图 1 稀疏矩阵示意图例如,图 1 是一个稀疏矩阵,若对其进行压缩存储,矩阵中各非 0 元素的存储状态如图 2 所示:图 2 稀疏矩阵的压缩存储示意图在图2的数组中,存储了一个三元组(即一组三个部分的数据),分别表示组中的数据(行标签、列标签和元素值)。

注意,这里矩阵的行和列标签都是从1开始的。

C 语言中,三元组需要用结构体实现,如下所示://三元组结构体typedef struct {int i,j;//行标i,列标jint data;//元素值}triple;由于稀疏矩阵中非 0 元素有多个,因此需要建立 triple 数组存储各个元素的三元组。

除此之外,考虑到还要存储矩阵的总行数和总列数,因此可以采用以下结构表示整个稀疏矩阵:#define number 20//矩阵的结构表示typedef struct {triple data[number];//存储该矩阵中所有非0元素的三元组int n,m,num;//n和m分别记录矩阵的行数和列数,num 记录矩阵中所有的非0元素的个数}TSMatrix;可以看到,TSMatrix 是一个结构体,其包含一个三元组数组,以及用于存储矩阵总行数、总列数和非 0 元素个数的变量。

假设采用 TSMatrix 结构体存储图 1 中的稀疏矩阵,其 C 语言实现代码应该为:#include<stdio.h>#define number 3typedef struct {int i,j;int data;}triple;typedef struct {triple data[number];int n,m,num;}TSMatrix;//输出存储的稀疏矩阵void display(TSMatrix M);int main() {TSMatrix M;M.m=3;M.n=3;M.num=3;M.data[0].i=1;M.data[0].j=1;M.data[0].data=1;M.data[1].i=2;M.data[1].j=3;M.data[1].data=5;M.data[2].i=3;M.data[2].j=1;M.data[2].data=3;display(M);return 0;}void display(TSMatrix M){for(int i=1;i<=M.n;i++){for(int j=1;j<=M.m;j++){int value =0;for(int k=0;k<M.num;k++){if(i == M.data[k].i && j ==M.data[k].j){printf("%d ",M.data[k].data); value =1;break;}}if(value == 0)printf("0 ");}printf("\n");}}输出结果为:1 0 00 0 53 0 0。

实验5稀疏矩阵三元组表的操作1

实验5稀疏矩阵三元组表的操作1

实验五稀疏矩阵三元组表的操作科目:数据结构实验和课程设计班级: 10信管姓名:徐杨学号:2010110450 实验目的:会定义稀疏矩阵的三元组表。

熟悉C语言程序的基本结构,掌握程序中的用户头文件、文件之间的相互关系及各自的作用。

熟悉对稀疏矩阵的三元组表的一些基本操作和具体的函数定义。

熟悉C语言操作环境的使用以及多文件程序的输入、编辑、调试和运行的全过程。

实验要求:认真阅读和掌握本实验内容所给的全部程序。

保存和输出程序运行结果,并结合程序进行分析。

按照你对稀疏矩阵的三元组表操作的需要,编写程序代码然后运行,给出运行结果。

实验设备:每人一台安装VC6.0编写软件的计算机,公用打印机。

注意事项:要在硬盘上建立好自己的工作目录,专门用来存储自己所做的实验程序及相关数据,以后每次做实验最好仍采用这个目录。

认真编写算法及运行结果,针对本实验的具体算法,认真写出算法分析。

一、实验步骤:#include<iostream.h>//稀疏矩阵三元组表的操作#define maxsize 64#define M#define Ntypedef int elemtype;struct node{int r,c;elemtype d;};struct ts{int rows,cols,nums;node data[maxsize];};void create(ts &a);//稀疏矩阵三元组表的建立void disp(ts a);//显示稀疏矩阵三元组表的内容void trants(ts a,ts &at); //求稀疏矩阵的转置void add(ts a,ts b,ts &c);//求两稀疏矩阵的和void main(){ts a;create(a); //稀疏矩阵三元组表的建立disp(a); //显示稀疏矩阵三元组表的内容ts at;trants(a,at); //求稀疏矩阵的转置disp(at); //显示转置矩阵的内容ts b;create(b);disp(b); //稀疏矩阵三元组表的建立ts c;add(a,b,c); //求两稀疏矩阵的和disp(c); //显示两稀疏矩阵和的内容}void create(ts &a) //稀疏矩阵三元组表的建立{ cout<<"建立稀疏矩阵三元组表:"<<endl;cout<<"稀疏矩阵的行数为:";cin>>a.rows;cout<<"稀疏矩阵列的数为:";cin>>a.cols;cout<<"稀疏矩阵中非零的元素个数为:";cin>>a.nums;cout<<"稀疏矩阵的三元组表为:"<<endl;for(int i=0;i<a.nums;i++){cin>>a.data[i].r>>a.data[i].c>>a.data[i].d;}}void disp(ts a) //显示稀疏矩阵三元组表的内容{ int i;cout<<"显示稀疏矩阵三元组表:"<<endl;if(a.nums<=0) return;cout<<"行数为:"<<a.rows<<" "<<"列数为:"<<a.cols<<" "<<"元素个数为:"<<" "<<a.nums<<endl;cout<<"------------------------"<<endl;for(i=0;i<a.nums;i++)cout<<a.data[i].r<<" "<<a.data[i].c <<" "<<a.data[i].d <<endl;}void trants(ts a,ts &at)//求稀疏矩阵的转置{ int p,q=0,v;at.rows=a.cols;at.cols=a.rows;at.nums=a.nums;if(a.nums!=0){ for(v=0;v<a.cols;v++)for(p=0;p<a.nums;p++)if(a.data[p].c==v){at.data[q].r=a.data[p].c;at.data[q].c=a.data[p].r;at.data[q].d=a.data[p].d;q++;}}cout<<"转置后的稀疏矩阵:"<<endl;}void add(ts a,ts b,ts &c) //求两稀疏矩阵的和{int i=0,j=0,k=0;elemtype v;if (a.rows!=b.rows||a.cols!=b.cols)c.rows=a.rows;c.cols=a.cols;while (i<a.nums&&j<b.nums){if(a.data[i].r==b.data[j].r){if(c.data[i].c<b.data[j].c){c.data[k].r=a.data[i].r;c.data[k].c=a.data[i].c;c.data[k].d=a.data[i].d;k++;i++;}else if(a.data[i].c>b.data[j].c){c.data[k].r=b.data[j].r;c.data[k].c=b.data[j].c;c.data[k].d=b.data[j].d;k++;j++;}else{v=a.data[i].d+b.data[j].d;if(v!=0){c.data[k].r=a.data[i].r;c.data[k].c=a.data[i].c;c.data[k].d=v;k++;}i++;j++;}}else if(a.data[i].r<b.data[j].r){c.data[k].r=a.data[i].r;c.data[k].c=a.data[i].c;c.data[k].d=a.data[i].d;k++;i++;}else{c.data[k].r=b.data[j].r;c.data[k].c=b.data[j].c;c.data[k].d=b.data[j].d;k++;j++;}c.nums=k;}cout<<"两个稀疏矩阵求和后元素的个数为:"<<c.nums<<endl; }二、运行结果:三、算法分析:。

稀疏矩阵——三元组顺序表

稀疏矩阵——三元组顺序表

稀疏矩阵——三元组顺序表⽬录稀疏矩阵假设m*n的矩阵中,有t的⾮零元,令s=t/m * n,当,s<=0.05时,称此矩阵为稀疏矩阵,简单理解就是⾮零元特别少的矩阵//⼀般矩阵a1 2 3a= 4 5 67 8 9//稀疏矩阵s0 0 0 0 00 2 0 0 5s= 0 0 3 0 00 0 0 0 4矩阵的转置⼀个m * n的矩阵转置后变为 n * m的矩阵//3*2的矩阵-转置前1 24 57 8//转置后变为2*31 4 72 5 8转置后的矩阵每个元素的下表与原来的下表刚好相反,例如上⾯4转置前的下标为(2,1),转置后变为(1,2);矩阵压缩存储-三元组顺序表之所以引⼊三元组顺序表,是因为,对于稀疏矩阵⽽⾔,⽤传统的存储⽅法会造成存储空间的浪费0 12 9 0 0 0 00 0 0 0 0 0 0-3 0 0 0 0 14 0M= 0 0 24 0 0 0 00 18 0 0 0 0 015 0 0 -7 0 0 0//上⾯矩阵⽤三元组表⽰i j v1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7typedef struct{int i,j; //⾏坐标、列坐标ElemType e; //元素}Triple;typedef struct{Triple date[MAXSIZE+1]; //0不存储元素int mu,nu,tu; //⾏数、列数、⾮零元个数}TSMatrix;稀疏矩阵的转置传统⽅法的转置算法时遍历矩阵的每⼀项,交换其下标值即可for(col=1;col<=nu;col++){for(row=1;row<=mu;row++){T[col][row]=M[row][col]}}//时间复杂度 : O(nu*mu)利⽤三元组顺序表进⾏存储的稀疏矩阵要想实现转置显然不能⽤上⾯的算法,下⾯介绍两种⽅法:第⼀种:以列序为主序的转置//置换前存储位置i j v1 2 12 -> M.date[1]1 3 9 -> M.date[2]3 1 -3 -> M.date[3]3 6 14 -> M.date[4]4 3 24 -> M.date[5]5 2 18 -> M.date[6]6 1 15 -> M.date[7]6 4 -7 -> M.date[8]//置换后存储位置i j v1 3 -3 -> T.date[1]1 6 15 -> T.date[2]2 1 12 -> T.date[3]2 5 18 -> T.date[4]3 1 9 -> T.date[5]3 4 24 -> T.date[6]4 6 -7 -> T.date[7]6 3 14 -> T.date[8]void TransposeSMatrix(TSMatrix *T1,TSMatrix *T2){T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){int q=1,col,p;for(col=1;col<=T1->nu;col++) //矩阵列循环{for(p=1;p<=T1->tu;p++) //遍历所有元素{if(T1->date[p].j==col) //当元素在col列时{T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;q++;}}}}}//上述代码,当矩阵运算为满时,即tu=mu*nu,其时间复杂度为O(nu*nu*mu)//这种情况与经典算法相⽐,虽节省了存储空间,但是效率较低第⼆种:快速转置第⼀种算法是通过遍历所有元素的下标,从⽽确定其在转置后数组中的位置,快速转置的思想就是,预先确定每⼀列第⼀个⾮零元在对应转置后的数组date中的位置;因此需要两个辅助数组num[]:⽤来存放每⼀列的⾮零元个数cpot[]:存放第⼀个⾮零元在转置后数组date中的位置num[]数组的值很好求,只需要遍历⼀次所有元素即可for(t=1;t<=T1->tu;t++)++num[T1->date[t].j];对于cpot[],有⼀个规律col 1 2 3 4 5 6 7num[col] 2 2 2 1 0 1 0cpot[col] 1 3 5 7 8 8 9//规律copt[1]=1copt[col]=copt[col-1]+num[col-1]代码:void FastTransposeSMatrix(TSMatrix *T1,TSMatrix *T2){int num[T1->nu],cpot[T1->nu];int col,p,q,t;T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){//初始化每列⾮零元个数为0for(col=1;col<=T1->nu;col++){num[col]=0;}//求每列⾮零元个数for(t=1;t<=T1->tu;t++){++num[T1->date[t].j];}//求每列第⼀个⾮零元转置后的位置cpot[1]=1;for(col=2;col<=T1->nu;col++){cpot[col]=num[col-1]+cpot[col-1];}//遍历所有元素for(p=1;p<=T1->tu;p++){col=T1->date[p].j; //获取列坐标q=cpot[col]; //获取新位置T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;++cpot[col]; //之所以这个地⽅要++,因为每列⾮零元可能不⽌⼀个 }}}完整代码:#include <stdio.h>#include <stdlib.h>#define MAXSIZE 12500 //⾮零元个数的最⼤值typedef int ElemType;typedef struct{int i,j;ElemType e;}Triple;typedef struct{Triple date[MAXSIZE+1];int mu,nu,tu;}TSMatrix;//输⼊元素void Insert(TSMatrix *T){printf("请依次输⼊⾏数i、列数j、⾮零元个数sum:\n");int sum ;scanf("%d%d%d",&T->mu,&T->nu,&sum);T->tu=sum;int x,y,num;printf("请依次输⼊矩阵⾮零元的⾏坐标i、列坐标j、元素值x:\n");printf("i j v\n");for(int i=1 ;i<=sum;i++){scanf("%d%d%d",&x,&y,&num);T->date[i].i=x;T->date[i].j=y;T->date[i].e=num;}}//第⼀种转置⽅法void TransposeSMatrix(TSMatrix *T1,TSMatrix *T2)T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){int q=1,col,p;for(col=1;col<=T1->nu;col++){for(p=1;p<=T1->tu;p++){if(T1->date[p].j==col){T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;q++;}}}}}//输出矩阵⾮零元void Show(TSMatrix *T){printf("转置后的矩阵:\n");printf("i j v\n");for(int i=1;i<=T->tu;i++){printf("%d %d %d\n",T->date[i].i,T->date[i].j,T->date[i].e); }}//快速转置void FastTransposeSMatrix(TSMatrix *T1,TSMatrix *T2){int num[T1->nu],cpot[T1->nu];int col,p,q,t;T2->mu=T1->nu;T2->nu=T1->mu;T2->tu=T1->tu;if(T1->tu){//初始化每列⾮零元个数为0for(col=1;col<=T1->nu;col++){num[col]=0;}//求每列⾮零元个数for(t=1;t<=T1->tu;t++){++num[T1->date[t].j];}cpot[1]=1;for(col=2;col<=T1->nu;col++){cpot[col]=num[col-1]+cpot[col-1];}for(p=1;p<=T1->tu;p++){col=T1->date[p].j;q=cpot[col];T2->date[q].i=T1->date[p].j;T2->date[q].j=T1->date[p].i;T2->date[q].e=T1->date[p].e;++cpot[col];}}}int main(){TSMatrix T,T1,*q,*p;p=&T;q=&T1;Insert(p);//测试第⼀种转置⽅法TransposeSMatrix(p, q);Show(q);//测试快速转置FastTransposeSMatrix(p, q);Show(q);}/* 测试请依次输⼊⾏数i、列数j、⾮零元个数sum:6 7 8请依次输⼊矩阵⾮零元的⾏坐标i、列坐标j、元素值x:1 2 121 3 93 1 -33 6 144 3 245 2 186 1 156 4 -7转置后的矩阵:i j v1 3 -31 6 152 1 122 5 183 1 93 4 244 6 -76 3 14转置后的矩阵:i j v1 3 -31 6 152 1 122 5 183 1 93 4 244 6 -76 3 14Program ended with exit code: 0*/我不⽣产代码,我只是代码的搬运⼯。

数据结构-稀疏矩阵的三元组表存储方法

数据结构-稀疏矩阵的三元组表存储方法

4 3 24 5 2 18
注意:
data 7 data 8
6 1 15 6 4 -7
mu=6 nu=7 tu=8
为了保存矩阵的行数、列 数和非零元素个数,还需 增设三个量:mu nu tu
3.三元组线性表的数据类型描述
#define MAXSIZE 12500 //非零元素个数的最大值
typedef struct{
用变量 a 存放矩阵 M 的形式如下:
a . data p i j e a .data 1 1 2 12 a .data 2 1 3 9 a .data 3 3 1 -3 a .data 4 3 6 14 a .data 5 4 3 24 a .data 6 5 2 18 a .data 7 6 1 15 a .data 8 6 4 -7 a. mu=6 a. nu=7 a. tu=8
用一个三元组(tupel3)存放矩阵中的 一个非零元素的行号、列号及该非零元素 的值。 一个三元组的形式为:(i , j, e)
一般情况下,一个稀疏矩阵中有若干个 非零元素,所以要用一个“三元组线性表” 来存放一个稀疏矩阵。
2.用顺序存储结构存放三元组线性表
存放形式: (按行顺序存放) data p i j e
a .data 5 4 3 24
b .data 5
a .data 6 5 2 18
b .data 6
a .data 7 6 1 15
b .data 7
a .data 8 6 4 -7
b .data 8
a. mu=6 a. nu=7 a. tu=8 注:p=1:8,寻找 j=col 的a.data[ p]
a. mu=6 a. nu=7 a. tu=8 求得

稀疏矩阵——精选推荐

稀疏矩阵——精选推荐

稀疏矩阵稀疏矩阵的定义 对于那些零元素数⽬远远多于⾮零元素数⽬,并且⾮零元素的分布没有规律的矩阵称为稀疏矩阵(sparse)。

⼈们⽆法给出稀疏矩阵的确切定义,⼀般都只是凭个⼈的直觉来理解这个概念,即矩阵中⾮零元素的个数远远⼩于矩阵元素的总数,并且⾮零元素没有分布规律。

稀疏矩阵的压缩存储 由于稀疏矩阵中⾮零元素较少,零元素较多,因此可以采⽤只存储⾮零元素的⽅法来进⾏压缩存储。

由于⾮零元素分布没有任何规律,所以在进⾏压缩存储的时侯需要存储⾮零元素值的同时还要存储⾮零元素在矩阵中的位置,即⾮零元素所在的⾏号和列号,也就是在存储某个元素⽐如aij的值的同时,还需要存储该元素所在的⾏号i和它的列号j,这样就构成了⼀个三元组(i,j,a[i][j])的线性表。

三元组可以采⽤顺序表⽰⽅法,也可以采⽤链式表⽰⽅法,这样就产⽣了对稀疏矩阵的不同压缩存储⽅式。

稀疏矩阵的存储⽅式 1.稀疏矩阵的三元组表⽰ 若把稀疏矩阵的三元组线性表按顺序存储结构存储,则称为稀疏矩阵的三元组顺序表。

顺序表中除了存储三元组外,还应该存储矩阵⾏数、列数和总的⾮零元素数⽬,这样才能唯⼀的确定⼀个矩阵。

typedef struct Triple{int row,col,e;}Triple;typedef struct TSMarix{Triple data[max+1];//data是⾮零元素三元组表,data[0]未⽤int m,n,len;//m:矩阵的⾏数,n:矩阵的列数,len:⾮零元素的个数}TSMarix; 稀疏矩阵的转置 ⾏列递增转置法---算法思想: 采⽤按照被转置矩阵三元组表A的序列(即转置后三元组表B中的⾏序)递增的顺序进⾏转置,并以此送⼊转置后矩阵的三元组表B中,这样⼀来,转置矩阵的三元组表B恰好是以“⾏序为主序”的 这种⽅法中,转置后的三元组表B仍按⾏序递增存放,必须多次扫描被转置矩阵的三元组表A,以保证被转置矩阵递增形式进⾏转置,因此要通过双重循环来完成#include <stdio.h>#include <stdlib.h>#define max 3typedef struct Triple{int row,col,e;}Triple;typedef struct TSMarix{Triple data[max+1];//data是⾮零元素三元组表,data[0]未⽤int m,n,len;//m:矩阵的⾏数,n:矩阵的列数,len:⾮零元素的个数}TSMarix;void CreateTSMarix(TSMarix *T){int i;printf("请输⼊矩阵的⾏数,列数,⾮零元素个数:\n") ;scanf("%d%d%d",&T->m,&T->n,&T->len);if(T->m<1||T->n<1||T->len<1||T->len>=max){printf("输⼊的数据有误!\n");exit(1);}printf("请输⼊⾮零元素的⾏下标,列下标,值(空格分开输⼊):\n");for(i=1;i<T->len+1;i++)scanf("%d%d%d",&T->data[i].row,&T->data[i].col,&T->data[i].e);}void TransposeTSMarix(TSMarix T,TSMarix *B)//B保存转置后的矩阵{B->n=T.m;//转置后B的列存储的T的⾏B->m=T.n;//转置后B的⾏存储的T的列B->len=T.len;//B的元素的个数和T的元素的个数⼀样不变int i,j,k;if(B->len>0){j=1;//转置后B元素中的下标for(k=1;k<=T.m;k++)//采⽤被转置矩阵的列序即转置后矩阵的⾏序增序排列{for(i=1;i<=T.len;i++){if(T.data[i].col==k)//从头到尾扫描表A,寻找col值为k的三元组进⾏转置{B->data[j].row=T.data[i].col;B->data[j].col=T.data[i].row;B->data[j].e=T.data[i].e;j++;}}}}}void Print(TSMarix T){int i;printf("元素的⾏下标,列下标,值为:\n");for(i=1;i<=T.len;i++){printf("\t%d\t%d\t%d\n",T.data[i].row,T.data[i].col,T.data[i].e);}}int main(){TSMarix T,B;printf("创建三元组表:\n");CreateTSMarix(&T);printf("输出三元组表:\n");Print(T);TransposeTSMarix(T,&B);printf("转置后的矩阵B为:\n");Print(B);return0;} ⼀次快速定位转置法---算法思想 1.待转置矩阵三元组表A每⼀列⾮零元素的总个数,即转置后矩阵三元组表B的每⼀⾏中⾮零元素的总个数 2.待转置矩阵每⼀列中第⼀个⾮零元素在三元组表B中的正确位置,即转置后矩阵每⼀⾏中的第⼀个⾮零元素在三元组表B 中的正确位置,需要增设两个数组,num[col]⽤来存放三元组表A第col列⾮零元素总个数(三元组表第col⾏⾮零元素总个数),position[col]⽤来存放转置前三元组表A中第col列(转置后三元组表B中第col⾏)中第⼀个⾮零元素在三元组表B中的存储位置(下标值)。

(10)稀疏矩阵的三元组表存储方法

(10)稀疏矩阵的三元组表存储方法

求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
a. mu=6 a. nu=7 a. tu=8
注:p=1..8,寻找 a.data[ p].j==col 寻找
2.求解步骤分析:p=1..8, q的值 求解步骤分析: 的值=7 求解步骤分析 的值
注意: 注意:
为了保存矩阵的行数、 为了保存矩阵的行数、列 数和非零元素个数, 数和非零元素个数,还需 增设三个量: 增设三个量:mu nu tu
mu=6 nu=7 tu=8
3.三元组线性表的数据类型描述 3.三元组线性表的数据类型描述
#define MAXSIZE 12500 typedef struc{ int ElemType }Triple; typedef struc{ Triple data [MAXSIZE+1]; //三元组表,data[0]不用 三元组表, 三元组表 不用 int mu , nu , tu ; }TSMatrix TSMatrix M ; //矩阵的行数、列数、非0元素个数 矩阵的行数、列数、 矩阵的行数 元素个数 //sparseness(稀疏 稀疏) 稀疏 i, j; e; //非零元素个数的最大值 非零元素个数的最大值
世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看世界那么世界那么大大我们去看我们去看看看sparsematrix例如
求解
b .data 4 b .data 5 b .data 6 b .data 7 b .data 8
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
//按矩阵形式输出M
void PrintTSMatrix1(TSMatrix M)
{
int i,j,k=1;
Triple *p=M.data;
p++; //p指向第一个非零元素
for(i=1;i<=M.mu;i++)
{
for(j=1;j<=M.nu;j++)
if(k<=M.tu&&p->i==i&&p->j==j) //p指向非零元,且p所指元素为当前处理元素
break;
case 0:
Q.data[++q]=M.data[m++]; //M、N矩阵当前非零元素的行列均相等
Q.data[q].e+=N.data[n++].e;//矩阵M、N的当前元素值求和并赋给矩阵Q
if(Q.data[q].e==0) //元素值为0,不存入压缩矩阵
q--;
break;
case 1: Q.data[++q]=N.data[n++];
for(j=1;j<=M.tu;j++) //对于M的每一个值
Tc[M.data[j].i]+=M.data[j].e*Nc[M.data[j].j];//Tc中存N的第i列与M相乘的结果
for(j=1;j<=M.mu;j++)
if(Tc[j]!=0)
{
T.data[++T.tu].e=Tc[j];
Tc=(ElemType*)malloc((M.nu+1)*sizeof(ElemType));//Tc为矩阵T一行的临时数组(非压缩,【0】不用)
if(!Nc||!Tc) //创建临时数组不成功
exit(ERROR);
for(i=1;i<=N.nu;i++) //对于N的每一列
{
for(j=1;j<=N.mu;j++)
}
//3.输出稀疏矩阵M
void PrintTSMatrix(TSMatrix M)
{
int i;
printf("%d行%d列%d个非零元素\n",M.mu,M.nu,M.tu);
printf("行列元素值\n");
for(i=1;i<=M.tu;i++)
printf("%2d%4d%8d\n",M.data[i].i,M.data[i].j,M.data[i].e);
int p, q, col;
T.mu = M.nu; T.nu = M.mu; T.tu = M.tu;
if (T.tu)
{
q = 1;
for (col=1; col<=M.nu; ++col)
for (p=1; p<=M.tu; ++p)
if (M.data[p].j == col)
{
T.data[q].i=M.data[p].j;,*Tc;
TSMatrix T; //临时矩阵
if(M.nu!=N.mu)
return ERROR;
T.nu=M.mu; //临时矩阵T是Q的转置矩阵
T.mu=N.nu;
T.tu=0;
Nc=(ElemType*)malloc((N.mu+1)*sizeof(ElemType));//Nc为矩阵N一列的临时数组(非压缩,【0】不用)
printf("矩阵C3(A的转置):\n");
PrintTSMatrix1(C);
printf("创建矩阵A2:");
CreateTSMatrix(A);
PrintTSMatrix1(A);
printf("创建矩阵B2:(行数应与矩阵A的列数相同=%d)\n",A.nu);
CreateTSMatrix(B);
T.data[T.tu].i=i;
T.data[T.tu].j=j;
}
}
if(T.tu>MAX_SIZE) //非零元素个数太多
return ERROR;
TransposeTSMatrix(T,Q); //将T的装置赋给Q
DestroyTSMatrix(T); //销毁临时矩阵T
free(Tc); //释放动态数组Tc和Nc
{
case -1:
Q.data[++q]=M.data[m++];//将矩阵M的当前元素值赋给矩阵Q
break;
case 0:
switch(comp(M.data[m].j,N.data[n].j)) //M、N矩阵当前元素的行相等,继续比较列
{
case -1:
Q.data[++q]=M.data[m++];
printf("请输入矩阵的行数,列数,非零元素数:");
scanf("%d%d%d",&M.mu,&M.nu,&M.tu);
if(M.tu>MAX_SIZE)
return ERROR;
M.data[0].i=0;//为以下比较顺序做准备
for(i=1;i<=M.tu;i++) //注意i从1开始的
Status TransposeTSMatrix(TSMatrix M, TSMatrix &T);
//主函数
void main()
{
TSMatrix A,B,C;
printf("创建矩阵A:\n");
CreateTSMatrix(A);
PrintTSMatrix(A);
printf("由矩阵A复制矩阵B:\n");
}
break;
case 1: Q.data[++q]=N.data[n++];//将矩阵N的当前元素值赋给矩阵Q
}
}
while(m<=M.tu)//矩阵N的元素全部处理完毕
Q.data[++q]=M.data[m++];
while(n<=N.tu)//矩阵M的元素全部处理完毕
Q.data[++q]=N.data[n++];
{
T=M;
}
//5.求稀疏矩阵的和Q=M+N,M和N的行数和列数相等
//AddTSMatrix()中要用到
int comp(int c1,int c2)
{
if(c1<c2)
return -1;
if(c1==c2)
return 0;
return 1;
}
Status AddTSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
}TSMatrix;
//函数声明
Status CreateTSMatrix(TSMatrix &M);
void DestroyTSMatrix(TSMatrix &M);
void PrintTSMatrix(TSMatrix M);
void PrintTSMatrix1(TSMatrix M);
void CopyTSMatrix(TSMatrix M,TSMatrix &T);
注意:
程序:加法、乘法不调用。
#include<stdio.h>
#include<stdlib.h> //稀疏矩阵的三元组顺序表存储表示
#define MAX_SIZE 12500 //假设非零元个数的最大值为12500
#define OK 1
#define ERROR 0
typedef int ElemType;
free(Nc);
return OK;
}
//8.求稀疏矩阵M的转置矩阵T TransposeTSMatrix(TSMatrix M,TSMatrix &T)
Status TransposeTSMatrix(TSMatrix M, TSMatrix &T)
{ //算法5.1
//采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T
{
printf("%3d",p->e);//输出p所指元素的值
p++;//p指向下一个元素
k++;//计数器+1
}
else //p所指元素不是当前处理元素
printf("%3d",0);//输出0
printf("\n");
}
}
//4.由稀疏矩阵M复制得到T
void CopyTSMatrix(TSMatrix M,TSMatrix &T)
Q.tu=q;//矩阵Q的非零元素个数
if(q>MAX_SIZE)//非零元素个数太多
return ERROR;
return OK;
}
//6.求稀疏矩阵的差Q=M-N,M和N的行数和列数相等
Status SubtTSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
{
PrintTSMatrix1(B);
//MultTSMatrix(A,B,C);
printf("矩阵C5(A*B):\n");
相关文档
最新文档