数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现

合集下载

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

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

稀疏矩阵的三元组顺序表存储表示及其转置算法目录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的情况下,只有少数非零元素的情况。

数据结构之稀疏矩阵稀疏矩阵的存储方式和操作分析

数据结构之稀疏矩阵稀疏矩阵的存储方式和操作分析

数据结构之稀疏矩阵稀疏矩阵的存储方式和操作分析稀疏矩阵是指矩阵中大部分元素为零的特殊矩阵。

在实际应用中,稀疏矩阵经常出现,如图像处理、网络分析和科学计算等领域。

对于稀疏矩阵的存储和操作是数据结构中的重要内容。

本文将介绍稀疏矩阵的存储方式和相关操作的分析。

一、稀疏矩阵存储方式稀疏矩阵的存储方式有多种,其中三元组顺序表和二维数组是比较常用的方法。

1. 三元组顺序表三元组顺序表是一种基于行优先存储的方式,可以将稀疏矩阵以非零元素的形式存储起来。

主要包括行号、列号和元素值三个信息。

以一个4x5的稀疏矩阵为例,其中有三个非零元素分别为A[1][2]=3, A[2][3]=4, A[3][4]=5。

可以使用三元组顺序表来存储:```行号列号元素值1 2 32 3 43 4 5```三元组顺序表的优点是可以节省存储空间,同时也方便进行矩阵的操作。

但是在进行元素的查找和修改时,效率较低。

2. 二维数组二维数组是一种常见的矩阵表示方法,可以直接使用二维数组来表示稀疏矩阵。

其中非零元素的位置用实际的值表示,其余位置用零值表示。

以同样的4x5的稀疏矩阵为例,使用二维数组存储如下:```0 0 0 0 00 0 3 0 00 0 0 4 00 0 0 0 5```二维数组的优点是简单直观,并且可以快速进行元素的查找和修改。

但当稀疏矩阵的规模较大时,会造成较高的存储资源浪费。

二、稀疏矩阵的操作分析对于稀疏矩阵的操作,主要包括矩阵的转置、相加、相乘等。

1. 转置操作稀疏矩阵的转置是指将原始矩阵的行与列对调。

对于三元组顺序表来说,转置操作主要涉及到行号和列号的交换。

而对于二维数组来说,可以直接在取值的时候将行号和列号对调即可。

2. 相加操作稀疏矩阵的相加操作是指将两个矩阵对应位置的元素相加。

对于三元组顺序表来说,可以通过遍历两个矩阵的非零元素,并将其对应位置的元素相加。

而对于二维数组来说,可以直接将对应位置的元素相加即可。

3. 相乘操作稀疏矩阵的相乘操作是指将两个矩阵相乘得到一个新的矩阵。

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

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

稀疏矩阵——三元组顺序表⽬录稀疏矩阵假设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*/我不⽣产代码,我只是代码的搬运⼯。

稀疏矩阵的三元组顺序表示方法C++代码

稀疏矩阵的三元组顺序表示方法C++代码

#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define MAXSIZE 100typedef int Status;typedef int ElemType;typedef struct{int i,j;ElemType e;}Triple;typedef struct{int mu,nu,tu;Triple data[MAXSIZE+1];}TSMatrix;Status CreatSMatrix(TSMatrix &M)//创建新的稀疏矩阵{printf("输入稀疏方阵的行数,列数以及非零元个数:");scanf("%d%d%d",&M.mu,&M.nu,&M.tu);while(M.tu>M.mu * M.nu){printf("输入稀疏方阵的行数,列数以及非零元个数:");scanf("%d%d%d",&M.mu,&M.nu,&M.tu);}int k;for( k=1;k<=M.tu;k++){printf("输入第%d个非0元素的行数,列数以及值:",k);scanf("%d%d%d",&M.data[k].i,&M.data[k].j,&M.data[k].e);if(M.data[k].i>M.mu || M.data[k].j>M.nu )printf("输入错误!\n");system("PAUSE");exit(1);}while(M.data[k].e==0){printf("输入的必须是非零元素!\n");scanf("%d,%d,%d",&M.data[k].i,&M.data[k].j,&M.data[k].e);}}return OK;}Status PrintSMatrix(TSMatrix &X){if(!X.tu){printf("矩阵为空!\n");return 0;}int i,j,k=1;for(i=1;i<=X.mu;i++){ for(j=1;j<=X.nu;j++){ if(i==X.data[k].i && j==X.data[k].j){printf("%2d ",X.data[k].e);k++;} else printf(" 0 ");}printf("\n");}return OK;}Status TransposeSMatrix(TSMatrix M,TSMatrix &T){T.mu = M.nu;T.nu = M.mu;T.tu = M.tu;if(T.tu){int col;int p;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;T.data[q].j = M.data[p].i;T.data[q].e = M.data[p].e;++q;}}return OK;}void main(){TSMatrix M;TSMatrix T;int choice;do{printf("\n请输入你的选择:\n");printf("1 创建稀疏矩阵\n");printf("2 该矩阵的转值\n");printf("0 退出\n");scanf("%d",&choice);switch(choice){case 1:printf("\n");CreatSMatrix(M);printf("\n");PrintSMatrix(M);break;case 2:printf("\n");TransposeSMatrix( M,T);printf("\n");PrintSMatrix(T);break;default:printf("\n\n你输入的信号无效!\n\n");break;}}while(choice!=0);}。

c语言 三元组表的存储结构描述

c语言 三元组表的存储结构描述

C语言三元组表的存储结构描述一、概述1. 三元组表是一种用于稀疏矩阵的存储结构,其主要用途是节省内存空间,提高数据存取效率。

2. 在C语言中,三元组表的存储结构通常采用数组来实现,具体来说,是通过定义一个结构体数组来表示稀疏矩阵。

二、结构定义3. 我们需要定义三元组表的结构体,该结构体通常由三个字段组成,分别表示稀疏矩阵的行标、列标和元素值。

4. 在C语言中,可以通过如下方式定义三元组表的结构体:```ctypedef struct{int row; // 行标int col; // 列标int value; // 元素值} Triplet;```三、存储方式5. 在C语言中,三元组表的存储方式通常采用一维数组来实现,数组中的每个元素都是一个三元组,用来表示稀疏矩阵中的一个非零元素。

6. 为了便于操作,通常还会在数组的第一个位置存储矩阵的行数、列数和非零元素的个数。

7. 以一个 3x3 的稀疏矩阵为例,其三元组表的存储结构可以表示为: ```c3 34 // 表示矩阵的行数、列数和非零元素的个数0 1 2 // 表示第一行第二列的元素值为21 0 -1 // 表示第二行第一列的元素值为-11 2 3 // 表示第二行第三列的元素值为32 2 1 // 表示第三行第三列的元素值为1```四、基本操作8. 三元组表的存储结构在C语言中通常会包含一些基本操作,以便对稀疏矩阵进行常见操作,例如转置、相加等。

9. 这些基本操作在C语言中通常会被封装成函数,例如:- create_triplet: 创建三元组表- print_triplet: 打印三元组表- transpose_triplet: 转置三元组表- add_triplet: 两个稀疏矩阵相加五、优缺点10. 三元组表的存储结构在C语言中具有一定的优点,包括节省存储空间、提高数据存取效率等。

11. 然而,其缺点在于需要额外的操作来处理稀疏矩阵,对于一般的稠密矩阵来说,可能并不适用。

数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现

数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现

数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现typedef int ElemType;// 稀疏矩阵得三元组顺序表存储表示#define MAXSIZE 100 // 非零元个数得最大值typedef struct{int i,j;?// 行下标,列下标ElemType e;// 非零元素值}Triple;typedef struct{Triple data[MAXSIZE+1];// 非零元三元组表,data[0]未用int mu,nu,tu;??//矩阵得行数、列数与非零元个数}TSMatrix;// 创建稀疏矩阵Mint CreateSMatrix(TSMatrix *M){inti,m,n;ElemType e;int k;printf("请输入矩阵得行数,列数,非零元素个数:(逗号)\n”);scanf(”%d,%d,%d”,&(*M)、mu,&(*M)、nu,&(*M)、tu);(*M)、data[0]、i=0;?// 为以下比较顺序做准备for(i = 1;i〈= (*M)、tu; i++){doprintf("请按行序顺序输入第%d个非零元素所在得行(1~%d),""列(1~%d),元素值:(逗号)\n", i,(*M)、mu,(*M)、n u);scanf("%d,%d,%d",&m,&n,&e);k=0;//行或列超出范围if(m 〈1 ||m 〉(*M)、mu||n<1 ||n > (*M)、nu)??k=1;if(m <(*M)、data[i—1]、i ||m== (*M)、data[i-1]、i&&n <= (*M)、data[i—1]、j) // 行或列得顺序有错k=1;}while(k);(*M)、data[i]、i = m;//行下标(*M)、data[i]、j = n;//列下标(*M)、data[i]、e = e;?//该下标所对应得值}return 1;}// 销毁稀疏矩阵M,所有元素置空void DestroySMatrix(TSMatrix *M){(*M)、mu=0;(*M)、nu=0;(*M)、tu=0;}// 输出稀疏矩阵MvoidPrintSMatrix(TSMatrixM)int i;printf("\n%d行%d列%d个非零元素。

C语言数据结构 稀疏矩阵

C语言数据结构 稀疏矩阵

实验十稀疏矩阵#include <stdio.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100typedef int Status;typedef float ElemType;typedef struct{int i,j; //非零元素行下标和列下标ElemType e; //非零元素值}Triple;typedef struct{Triple data[MAXSIZE+1];//非零元三元组表,data[0]不用int mu,nu,tu; //矩阵的行数、列数和非零元素个数}TSMatrix;TSMatrix NewMatrix(int m,int n); //新建一个三元组表示的稀疏矩阵Status InsertElem(TSMatrix *M,int row,int col,ElemType e);//在三元组表示的稀疏矩阵M,第row 行,第col 列位置插入元素e//插入成功,返回OK,否则返回ERRORStatus FindElem(const TSMatrix *M,int row,int col,ElemType *e);//查找三元组表示的稀疏矩阵M中,第row 行,第col列元素,若不为0,//则用e返回其值,并返回TRUE,否则返回FALSEStatus TransposeSMatrix(const TSMatrix *M,TSMatrix *T);//采用三元组表存储表示,求稀疏矩阵M的转置矩阵TStatus FastTransposeSMatrix(const TSMatrix *M,TSMatrix *T);//利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵TStatus MultSMatrix(const TSMatrix *M,const TSMatrix *T,TSMatrix *Q);//稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERRORvoid PrintSMatrix(const TSMatrix *M);//打印稀疏矩阵所有元素int main() {TSMatrix M=NewMatrix(3,4);TSMatrix T;TSMatrix Q;InsertElem(&M,3,2,3.65);InsertElem(&M,2,2,2.31);printf("\nM:");PrintSMatrix(&M);FastTransposeSMatrix(&M,&T);printf("\nT(Transpose of M):");PrintSMatrix(&T);MultSMatrix(&M,&T,&Q);printf("\nM*T=");PrintSMatrix(&Q);return 0;}TSMatrix NewMatrix(int m,int n){ //新建一个三元组表示的稀疏矩阵TSMatrix M;M.mu=m;M.nu=n;M.tu=0;return M;}Status InsertElem(TSMatrix *M,int row,int col,ElemType e){ //在三元组表示的稀疏矩阵M,第row 行,第col 列位置插入元素e//插入成功,返回OK,否则返回ERRORint i,t,p;if(M->tu>=MAXSIZE){//当前三元组表已满printf("\nError:There is no space in the matrix;\n");return ERROR;}if(row>M->mu||col>M->nu||row<1||col<1)//插入位置越界,不在1~mu或1~nu之间{printf("\nError:Insert position is beyond thearrange.\n");return ERROR;}p=1; //标志新元素应该插入的位置if(M->tu==0) //插入前矩阵M没有非零元素{M->data[p].i=row;M->data[p].j=col;M->data[p].e=e;M->tu++;return OK; }for(t=1;t<=M->tu;t++)//寻找合适的插入位置if((row>=M->data[t].i)&&(col>=M->data[t].j))p++;if(row==M->data[t-1].i && col==M->data[t-1].j){//插入前,该元素已经存在M->data[t-1].e=e;return OK; }for(i=M->tu;i>=p;i--){//移动p之后的元素M->data[i+1].i=M->data[i].i;M->data[i+1].j=M->data[i].j;M->data[i+1].e=M->data[i].e;} //插入新元素M->data[p].i=row;M->data[p].j=col;M->data[p].e=e;M->tu++;return OK; }Status FindElem(const TSMatrix *M,int row,int col,ElemType *e){//查找三元组表示的稀疏矩阵M中,第row 行,第col列元素,若不为0,//则用e返回其值,并返回TRUE,否则返回FALSEint p; for(p=1;p<=M->tu;p++)if(M->data[p].i==row&&M->data[p].j==col){*e=M->data[p].e;return TRUE;}return FALSE; }Status TransposeSMatrix(const TSMatrix *M,TSMatrix *T){//采用三元组表存储表示,求稀疏矩阵M的转置矩阵Tint col,p,q;T->mu=M->nu;T->nu=M->mu; T->tu=M->tu;if(T->tu){q=1;for(col=1;col<=M->mu;col++)for(p=1;p<=M->tu;p++)if(M->data[p].j==col){T->data[q].i=M->data[p].j;T->data[q].j=M->data[p].i;T->data[q].e=M->data[p].e;q++;}}return OK; }Status FastTransposeSMatrix(const TSMatrix *M,TSMatrix *T){//利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵Tint col,t,p,q,*num,*cpot;T->mu=M->nu;T->nu=M->mu;T->tu=M->tu;if(T->tu){num=(int *)malloc(sizeof(int)*M->tu);cpot=(int *)malloc(sizeof(int)*M->tu);if(!(num&&cpot)){printf("Apply for memory error.\n");exit(0);}for(col=1;col<=M->nu;col++)num[col]=0; //求M中每一列含有非零元素的个数for(t=1;t<=M->tu;t++)++num[M->data[t].j];cpot[1]=1; //求第col列中第一个非零元素在b.data中的序号for(col=2;col<=M->nu;col++)cpot[col]=cpot[col-1]+num[col-1];for(p=1;p<=M->tu;p++){col=M->data[p].j;q=cpot[col];T->data[q].i=M->data[p].j;T->data[q].j=M->data[p].i;T->data[q].e=M->data[q].e;++cpot[col];}//for}//ifreturn OK; }Status MultSMatrix(const TSMatrix *M,const TSMatrix *T,TSMatrix *Q){//稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T 结果,并返回OK,否则返回ERRORint i,j,k,p;ElemType m,t,s;if(M->nu!=T->mu){printf("Sorry,these two matrice can't multiply.\n");return ERROR; }Q->mu=M->mu;Q->nu=T->nu;Q->tu=0;p=1;for(i=1;i<=Q->mu;i++){for(j=1;j<=Q->nu;j++){s=0;for(k=1;k<=M->nu;k++){if(FALSE==FindElem(M,i,k,&m))continue;if(FALSE==FindElem(T,k,j,&t))continue;s+=m*t; }if(s!=0){//Q[i][j]非零Q->data[p].i=i;Q->data[p].j=j;Q->data[p].e=s;p++;Q->tu++;}}}return OK;}void PrintSMatrix(const TSMatrix *M) {//打印稀疏矩阵所有元素int i,j,p=1;printf("\nsize:%d %d\n",M->mu,M->nu);if(!M->tu){//0矩阵printf("%g\n",0.0);return; }for(i=1;i<=M->mu;i++){for(j=1;j<=M->nu;j++){if(i==M->data[p].i&&j==M->data[p].j) {printf("%g\t",M->data[p].e);p++;}else{printf("%g\t",0.0);}}printf("\n");}printf("\n");}。

稀疏矩阵(C语言描述)

稀疏矩阵(C语言描述)

//矩阵减法实现主模块
{
void PRINTF(RLSMatrix*Result); Result->tu=0 ; Result->mu=A->mu ; Result->nu=A->nu ; int x=1 ; int y=1 ; int z=1 ;
while(x<=A->tu) {
if(A->data[x].i<B->data[y].i) {
void PRINTF(RLSMatrix*Result);
int ctemp[MAXRC]; int tp,p,t,arow,brow,q,ccol,i ;
Result->mu=A->mu ; Result->nu=B->nu ; Result->tu=0 ; if(A->tu*B->tu!=0) {
基本操作:
第 1 页 共 12 页
-=数据结构试验报告=-
系数矩阵运算器
creat( ) 操作结果:以一个二维数组创建稀疏矩阵,用三元组来存储. add(RLSMatrix M , RLSMatrix N) 初始条件:稀疏矩阵 M 与 N 的行数与列数对应相等. 操 作结果:求得一个矩阵和. jian(RLSMatrix a,RLSMatrix b) 初始条件:稀疏矩阵 M 与 N 的行数与列数对应相等. 操 作结果:求得一个矩阵差. transpose(RLSMatrix M) 初始条件:稀疏矩阵 M 存在 操作结果:求稀疏矩阵 M 的转置矩阵. value(RLSMatrix M,int m,int n) 初始条件:稀疏矩阵 M 存在. 操作结果:求出三元组存储中第 m 行第 n 列的数值. print1(RLSMatrix M) 初始条件:稀疏矩阵 M 存在. 操作结果:按矩阵的形式输出
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

typedef int ElemType;// 稀疏矩阵的三元组顺序表存储表示#define MAXSIZE 100 // 非零元个数的最大值typedef struct{int i,j; // 行下标,列下标ElemType e; // 非零元素值}Triple;typedef struct{Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用int mu,nu,tu; // 矩阵的行数、列数和非零元个数}TSMatrix;// 创建稀疏矩阵Mint CreateSMatrix(TSMatrix *M){int i,m,n;ElemType e;int k;printf("请输入矩阵的行数,列数,非零元素个数:(逗号)\n");scanf("%d,%d,%d",&(*M).mu,&(*M).nu,&(*M).tu);(*M).data[0].i=0; // 为以下比较顺序做准备for(i = 1; i <= (*M).tu; i++){do{printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),""列(1~%d),元素值:(逗号)\n", i,(*M).mu,(*M).nu);scanf("%d,%d,%d",&m,&n,&e);k=0;// 行或列超出范围if(m < 1 || m > (*M).mu || n < 1 || n > (*M).nu)k=1;if(m < (*M).data[i-1].i || m == (*M).data[i-1].i&& n <= (*M).data[i-1].j) // 行或列的顺序有错k=1;}while(k);(*M).data[i].i = m; //行下标(*M).data[i].j = n; //列下标(*M).data[i].e = e; //该下标所对应的值}return 1;}// 销毁稀疏矩阵M,所有元素置空void DestroySMatrix(TSMatrix *M){(*M).mu=0;(*M).nu=0;(*M).tu=0;}// 输出稀疏矩阵Mvoid PrintSMatrix(TSMatrix M){int i;printf("\n%d行%d列%d个非零元素。

\n",M.mu,M.nu,M.tu);printf("%4s%4s%8s\n", "行", "列", "元素值");for(i=1;i<=M.tu;i++)printf("%4d%4d%8d\n",M.data[i].i,M.data[i].j,M.data[i].e); }// 由稀疏矩阵M复制得到Tint CopySMatrix(TSMatrix M,TSMatrix *T){(*T)=M;return 1;}// AddSMatrix函数要用到int comp(int c1,int c2){int i;if(c1<c2)i=1;else if(c1==c2)i=0;elsei=-1;return i;}// 求稀疏矩阵的和Q=M+Nint AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){Triple *Mp,*Me,*Np,*Ne,*Qh,*Qe;if(M.mu!=N.mu)return 0;if(M.nu!=N.nu)return 0;(*Q).mu=M.mu;(*Q).nu=M.nu;Mp=&M.data[1]; // Mp的初值指向矩阵M的非零元素首地址Np=&N.data[1]; // Np的初值指向矩阵N的非零元素首地址Me=&M.data[M.tu]; // Me指向矩阵M的非零元素尾地址Ne=&N.data[N.tu]; // Ne指向矩阵N的非零元素尾地址Qh=Qe=(*Q).data; // Qh、Qe的初值指向矩阵Q的非零元素首地址的前一地址while(Mp <= Me && Np <= Ne){Qe++;switch(comp(Mp->i,Np->i)){case 1:*Qe=*Mp;Mp++;break;case 0:// M、N矩阵当前非零元素的行相等,继续比较列switch(comp(Mp->j,Np->j)){case 1:*Qe=*Mp;Mp++;break;case 0:*Qe=*Mp;Qe->e+=Np->e;if(!Qe->e) // 元素值为0,不存入压缩矩阵Qe--;Mp++;Np++;break;case -1:*Qe=*Np;Np++;}break;case -1:*Qe=*Np;Np++;}}if(Mp>Me) // 矩阵M的元素全部处理完毕while(Np<=Ne){Qe++;*Qe=*Np;Np++;}if(Np>Ne) // 矩阵N的元素全部处理完毕while(Mp<=Me){Qe++;*Qe=*Mp;Mp++;}(*Q).tu=Qe-Qh; // 矩阵Q的非零元素个数return 1;}// 求稀疏矩阵的差Q=M-Nint SubtSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){int i;for(i=1;i<=N.tu;i++)N.data[i].e*=-1;AddSMatrix(M,N,Q);return 1;}// 求稀疏矩阵的乘积Q=M*Nint MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){int i,j,h=M.mu,l=N.nu,Qn=0;// h,l分别为矩阵Q的行、列值,Qn为矩阵Q的非零元素个数,初值为0 ElemType *Qe;if(M.nu!=N.mu)return 0;(*Q).mu=M.mu;(*Q).nu=N.nu;Qe=(ElemType *)malloc(h*l*sizeof(ElemType)); // Qe为矩阵Q的临时数组// 矩阵Q的第i行j列的元素值存于*(Qe+(i-1)*l+j-1)中,初值为0for(i=0;i<h*l;i++)*(Qe+i)=0; // 赋初值0for(i=1;i<=M.tu;i++) // 矩阵元素相乘,结果累加到Qefor(j=1;j<=N.tu;j++)if(M.data[i].j==N.data[j].i)*(Qe+(M.data[i].i-1)*l+N.data[j].j-1) +=M.data[i].e * N.data[j].e;for(i=1;i<=M.mu;i++)for(j=1;j<=N.nu;j++)if(*(Qe+(i-1)*l+j-1)!=0){Qn++;(*Q).data[Qn].e=*(Qe+(i-1)*l+j-1);(*Q).data[Qn].i=i;(*Q).data[Qn].j=j;}free(Qe);(*Q).tu=Qn;return 1;}// 算法5.1 P99// 求稀疏矩阵M的转置矩阵T。

int TransposeSMatrix(TSMatrix M,TSMatrix *T){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;(*T).data[q].j=M.data[p].i;(*T).data[q].e=M.data[p].e;++q;}}return 1;}// 算法5.2 P100// 快速求稀疏矩阵M的转置矩阵T。

int FastTransposeSMatrix(TSMatrix M,TSMatrix *T){int p,q,t,col,*num,*cpot;num=(int *)malloc((M.nu+1)*sizeof(int)); // 生成数组([0]不用)cpot=(int *)malloc((M.nu+1)*sizeof(int)); // 生成数组([0]不用)(*T).mu=M.nu;(*T).nu=M.mu;(*T).tu=M.tu;if((*T).tu){for(col=1;col<=M.nu;++col)num[col]=0; // 设初值for(t=1;t<=M.tu;++t) // 求M中每一列含非零元素个数++num[M.data[t].j];cpot[1]=1;// 求第col列中第一个非零元在(*T).data中的序号for(col=2;col<=M.nu;++col)cpot[col]=cpot[col-1]+num[col-1];for(p=1;p<=M.tu;++p){col=M.data[p].j;q=cpot[col];(*T).data[q].i=M.data[p].j;(*T).data[q].j=M.data[p].i;(*T).data[q].e=M.data[p].e;++cpot[col];}}free(num);free(cpot);return 1;}int main(){TSMatrix A,B,C;printf("创建矩阵A: ");CreateSMatrix(&A);PrintSMatrix(A);printf("由矩阵A复制矩阵B: ");CopySMatrix(A,&B);PrintSMatrix(B);DestroySMatrix(&B);printf("销毁矩阵B后:\n");PrintSMatrix(B);printf("重创矩阵B:(注意与矩阵A的行、列数相同,这样方便后面的测试""行、列分别为%d,%d)\n", A.mu, A.nu);CreateSMatrix(&B);PrintSMatrix(B);printf("矩阵C1(A+B): ");AddSMatrix(A,B,&C);PrintSMatrix(C);DestroySMatrix(&C);printf("矩阵C2(A-B): ");SubtSMatrix(A,B,&C);PrintSMatrix(C);DestroySMatrix(&C);printf("矩阵C3(A的转置): ");TransposeSMatrix(A,&C);PrintSMatrix(C);DestroySMatrix(&A);DestroySMatrix(&B);DestroySMatrix(&C);printf("创建矩阵A2: ");CreateSMatrix(&A);PrintSMatrix(A);printf("创建矩阵B3:(行数应与矩阵A2的列数相同=%d)\n",A.nu); CreateSMatrix(&B);PrintSMatrix(B);printf("矩阵C5(A*B): ");MultSMatrix(A,B,&C);PrintSMatrix(C);DestroySMatrix(&A);DestroySMatrix(&B);DestroySMatrix(&C);printf("创建矩阵A: ");CreateSMatrix(&A);PrintSMatrix(A);FastTransposeSMatrix(A,&B);printf("矩阵B(A的快速转置): ");PrintSMatrix(B);DestroySMatrix(&A);DestroySMatrix(&B);system("pause");return 0;}/*输出效果:创建矩阵A: 请输入矩阵的行数,列数,非零元素个数:(逗号)3,3,3请按行序顺序输入第1个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,1,1请按行序顺序输入第2个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,3,2请按行序顺序输入第3个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 3,3,33行3列3个非零元素。

相关文档
最新文档