当前位置:文档之家› 三元组表示稀疏矩阵的转置(一般算法和快速算法)

三元组表示稀疏矩阵的转置(一般算法和快速算法)

一、设计要求1.1 问题描述稀疏矩阵是指那些多数元素为零的矩阵。

利用稀疏特点进行存储和计算可以大大节省存储空间,提高计算效率。

求一个稀疏矩阵A的转置矩阵B。

1.2需求分析(1)以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现稀疏矩阵的转置运算。

(2)稀疏矩阵的输入形式采用三元组表示,运算结果则以通常的阵列形式列出。

(3)首先提示用户输入矩阵的行数、列数、非零元个数,再采用三元组表示方法输入矩阵,然后进行转置运算,该系统可以采用两种方法,一种为一般算法,另一种为快速转置算法。

(4)程序需要给出菜单项,用户按照菜单提示进行相应的操作。

二、概要设计2.1存储结构设计采用“带行逻辑链接信息”的三元组顺序表表示矩阵的存储结构。

三元组定义为:typedef struct{int i;//非零元的行下标int j;//非零元的列下标ElemType e; //非零元素值}Triple;矩阵定义为:Typedef struct{Triple data[MAXSIZE+1]; //非零元三元组表int rpos[MAXRC+1]; //各行第一个非零元的位置表int mu,nu,tu; //矩阵的行数、列数和非零元个数}RLSMatrix;例如有矩阵A,它与其三元组表的对应关系如图2.2 系统功能设计本系统通过菜单提示用户首先选择稀疏矩阵转置方法,然后提示用户采用三元组表示法输入数据创建一个稀疏矩阵,再进行矩阵的转置操作,并以通常的阵列形式输出结果。

主要实现以下功能。

(1)创建稀疏矩阵。

采用带行逻辑连接信息的三元组表表示法,提示用户输入矩阵的行数、列数、非零元个数以及各非零元所在的行、列、值。

(2)矩阵转置。

<1>采用一般算法进行矩阵的转置操作,再以阵列形式输出转置矩阵B。

<2>采用快速转置的方法完成此操作,并以阵列形式输出转置矩阵B。

三、模块设计3.1 模块设计程序包括两个模块:主程序模块、矩阵运算模块。

3.2 系统子程序及其功能设计系统共设置了8个子程序,各子程序的函数名及功能说明如下。

(1)CreateSMatrix(RLSMatrix &M) //创建稀疏矩阵(2)void DestroySMatrix(RLSMatrix &M) //销毁稀疏矩阵(3)void PrinRLSMatrix(RLSMatrix M) //遍历稀疏矩阵(4)void print(RLSMatrix A) //打印矩阵函数,输出以阵列形式表示的矩阵(5)TransposeSMatrix(RLSMatrix M,RLSMatrix &T) //求稀疏矩阵的转置的一般算法(6)FastTransposeSMatrix(RLSMatrix M,RLSMatrix &T) //快速转置算法(7)void showtip() //工作区函数,显示程序菜单(8)void main() //主函数3.3 程序主要调用关系图四、详细设计4.1 数据类型定义采用矩阵“带行逻辑连接信息”的三元组顺序表存储结构。

4.2 系统主要子程序详细设计(1)主函数:void main(){int result;int j;RLSMatrix A,B;COORD Co={0,0};DWORD Write;SetConsoleTitle("稀疏矩阵的转置");HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(hOut,FOREGROUND_RED|FOREGROUND_BLUE|FOREGRO UND_INTENSITY);FillConsoleOutputAttribute(hOut,FOREGROUND_RED|FOREGROUND_BLUE|FOREGR OUND_INTENSITY,100000000,Co,&Write);///windows的API函数,用来设置控制台标题及颜色。

do{showtip(); //调用菜单函数int i;scanf("%d",&i);switch(i){case 1:printf("创建矩阵A:");if((result=CreateSMatrix(A))==0)exit(ERROR);printf("矩阵A的三元组表为:\n");PrinRLSMatrix(A);printf("求A的转置矩阵B(一般算法):\n");TransposeSMatrix(A,B);printf("矩阵B的三元组表为:\n");PrinRLSMatrix(B);printf("以通常的阵列形式输出转置前的矩阵A:\n");print(A);printf("\n\n");printf("以通常的阵列形式输出转置后的矩阵B:\n");print(B);DestroySMatrix(B);printf("\n\n");break;case 2:printf("创建矩阵A:");if((result=CreateSMatrix(A))==0)exit(ERROR);printf("矩阵A的三元组表为:\n");PrinRLSMatrix(A);printf("求A的转置矩阵B(快速转置):\n");FastTransposeSMatrix(A,B);printf("矩阵B的三元组表为:\n");PrinRLSMatrix(B);printf("以通常的阵列形式输出转置前的矩阵A:\n");print(A);printf("\n\n");printf("以通常的阵列形式输出转置后的矩阵B:\n");print(B);DestroySMatrix(A);DestroySMatrix(B);printf("\n\n");break;case 3:printf("创建矩阵A:");if((result=CreateSMatrix(A))==0)exit(ERROR);printf("矩阵A的三元组表为:\n");PrinRLSMatrix(A);printf("求A的转置矩阵B------(一般算法):\n");TransposeSMatrix(A,B);printf("矩阵B的三元组表为:\n");PrinRLSMatrix(B);printf("以通常的阵列形式输出转置前的矩阵A:\n");print(A);printf("\n\n");printf("以通常的阵列形式输出转置后的矩阵B:\n");print(B);DestroySMatrix(B);printf("\n\n");printf("求A的转置矩阵B------(快速转置):\n");FastTransposeSMatrix(A,B);printf("矩阵B的三元组表为:\n");PrinRLSMatrix(B);printf("以通常的阵列形式输出转置前的矩阵A:\n");print(A);printf("\n\n");printf("以通常的阵列形式输出转置后的矩阵B:\n\n\n\n");print(B);DestroySMatrix(A);DestroySMatrix(B);printf("\n\n");break;}printf(" **********请选择是否继续输入其他稀疏矩阵?**********\n\n");printf(" 1 是,输入其他矩阵\n");printf(" 0 否,不输入\n\n");printf("****************************************************\n\n\n\n\n\n\n\n\n\n");fflush(stdin);//清除输入缓存区scanf("%d",&j);}while(j==1);}(2)创建矩阵CreateSMatrix(RLSMatrix &M) //创建稀疏矩阵M{int i,m,n;ElemType e;int k,j;printf("输入矩阵的行数、列数、非零元的个数:");scanf("%d%d%d",&M.mu,&M.nu,&M.tu);M.data[0].i=0;for(i=1;i<=M.tu;i++){j=0;do{j++;if(j>3) //控制跳出死循环{printf("本次输入失败!");return ERROR;}printf("按行序输入第%d个非零元素所在的行(1~%d)列(1~%d)值:",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;} //end forprintf("\n");return(OK);}(3)销毁矩阵void DestroySMatrix(RLSMatrix &M) //销毁稀疏矩阵M{M.mu=0;M.nu=0;M.tu=0;}(4)遍历矩阵void PrinRLSMatrix(RLSMatrix M) //遍历稀疏矩阵M{int i;printf("稀疏矩阵对应的三元组表为:\n\n");printf("行列元素值、\n\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);printf("\n\n");}(5)打印矩阵函数void print(RLSMatrix A) //打印矩阵函数,以通常形式输出矩阵{int k=1,a,b;printf("稀疏矩阵的通常形式为:\n\n");int M[MAXSIZE][MAXSIZE];for(a=0;a<A.mu;a++) //初始化矩阵M{for(b=0;b<A.nu;b++)M[a][b]=0;}while(k<=A.tu){M[A.data[k].i-1][A.data[k].j-1]=A.data[k].e;k++;}for(a=0;a<A.mu;a++){printf(" | ");for(b=0;b<A.nu;b++)printf("%d ",M[a][b]);printf(" | \n");}}(6)工作区函数,显示程序菜单void showtip() //菜单{printf(" ********************请选择要执行的操作********************\n\n");printf(" 1 采用一般算法实现\n\n");printf(" 2 采用快速转置的算法实现\n\n");printf("**********************************************************\n");}(7)矩阵的转置(一般算法)TransposeSMatrix(RLSMatrix M,RLSMatrix &T) //求稀疏矩阵M的转置矩阵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 OK;}(8)快速转置算法采用此算法时引用两个辅助数组num[],cpot[], num[col]表示矩阵M中第col列中非零元的个数,cpot[col]指示M中第col列的第一个非零元在b.data中的恰当位置。

相关主题