数组与广义表的算法的实验报告.docx
- 文档编号:27081339
- 上传时间:2023-06-26
- 格式:DOCX
- 页数:45
- 大小:383.43KB
数组与广义表的算法的实验报告.docx
《数组与广义表的算法的实验报告.docx》由会员分享,可在线阅读,更多相关《数组与广义表的算法的实验报告.docx(45页珍藏版)》请在冰豆网上搜索。
数组与广义表的算法的实验报告
数组与广义表的算法
实验工具:
visualC++
实验容:
1、三元组表示稀疏矩阵的转置算法(一般&快速)<1-7页>2、稀疏矩阵乘法、加法的算法(一般&十字链表)<8-21页>3、广义表的各种算法<22-28页>
体验:
通过利用visualC++实验工具,实现数组与广义表各类算法的过程中,本人对数组与广义表的知识有了更深的了解,而且认识到数组与广义表各类操作可由形式多样的算法结构实现。
算法并非统一标准的,同样的结果可有多种算法得出,算法的编写鼓励创造性思维。
1、三元组表示稀疏矩阵的转置算法(一般&快速)
代码:
#include
#include
#include
#include
#defineOK1
#defineERROR0
#defineOVERFLOW0
#defineMAXSIZE100
#defineMAXRC100
typedefintElemType;
typedefstruct
{
inti,j;
ElemTypee;
}Triple;
typedefstruct
{
Tripledata[MAXSIZE+1];//非零元三元组
intrpos[MAXRC+1];//各行第一个非零元的位置表
intmu,nu,tu;//矩阵的行数、列数和非零元个数
}RLSMatrix;
CreateSMatrix(RLSMatrix&M)//创建稀疏矩阵M
{
inti,m,n;
ElemTypee;
intk,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("本次输入失败!
");
returnERROR;
}
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 k=1; }while(k); M.data[i].i=m; M.data[i].j=n; M.data[i].e=e; }//endfor printf("\n"); return(OK); } voidDestroySMatrix(RLSMatrix&M)//销毁稀疏矩阵M { M.mu=0; M.nu=0; M.tu=0; } voidPrinRLSMatrix(RLSMatrixM)//遍历稀疏矩阵M { inti; 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"); } voidprint(RLSMatrixA)//打印矩阵函数,以通常形式输出矩阵 { intk=1,a,b; printf("稀疏矩阵的通常形式为: \n"); intM[MAXSIZE][MAXSIZE]; for(a=0;a { for(b=0;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 { printf("|"); for(b=0;b printf("%d",M[a][b]); printf("|\n"); } } voidshowtip()//菜单 { printf("********************请选择要执行的操作********************\n\n"); printf("&1采用一般算法实现&\n"); printf("&2采用快速转置的算法实现&\n"); printf("&3同时采用两种算法,先显示一般算法,再显示快速算法&\n"); printf("**********************************************************\n\n"); } ////头文件结束 TransposeSMatrix(RLSMatrixM,RLSMatrix&T)//求稀疏矩阵M的转置矩阵T(一般算法) { intp,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; } } returnOK; } FastTransposeSMatrix(RLSMatrixM,RLSMatrix&T)//快速转置算法 { intp,q,t,col,*num,*cpot; num=(int*)malloc((M.nu+1)*sizeof(int)); cpot=(int*)malloc((M.nu+1)*sizeof(int)); 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) ++num[M.data[t].j]; cpot[1]=1; for(col=2;col<=M.nu;++col) cpot[col]=cpot[col-1]+num[col-1]; printf("\n辅助数组的值为: \n"); printf("列号: "); for(t=1;t<=M.nu;++t) printf("%4d",t); printf("\n"); printf("num[]"); for(t=1;t<=M.nu;++t) printf("%4d",num[t]); printf("\n"); printf("cpot[]"); for(t=1;t<=M.nu;++t) printf("%4d",cpot[t]); printf("\n\n"); 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); returnOK; } voidmain() { intresult; intj; RLSMatrixA,B; //************************************************ COORDCo={0,0};DWORDWrite; SetConsoleTitle("稀疏矩阵的转置\n"); HANDLEhOut=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hOut,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY); FillConsoleOutputAttribute(hOut,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_INTENSITY,100000000,Co,&Write); ///windows的API函数,用来设置控制台标题 do { showtip();//调用菜单函数 inti; scanf("%d",&i); switch(i) { case1: printf("创建矩阵A: "); if((result=CreateSMatrix(A))==0) exit(ERROR); PrinRLSMatrix(A); printf("求A的转置矩阵B(一般算法): \n"); TransposeSMatrix(A,B); PrinRLSMatrix(B); print(B); DestroySMatrix(B); printf("\n\n");break; case2: printf("创建矩阵A: "); if((result=CreateSMatrix(A))==0) exit(ERROR); PrinRLSMatrix(A); printf("求A的转置矩阵B(快速转置): \n"); FastTransposeSMatrix(A,B); PrinRLSMatrix(B); print(B); DestroySMatrix(A); DestroySMatrix(B); printf("\n\n");break; case3: printf("创建矩阵A: "); if((result=CreateSMatrix(A))==0) exit(ERROR); PrinRLSMatrix(A); printf("求A的转置矩阵B------(一般算法): \n"); TransposeSMatrix(A,B); PrinRLSMatrix(B); print(B); DestroySMatrix(B); printf("\n\n"); printf("求A的转置矩阵B------(快速转置): \n"); FastTransposeSMatrix(A,B); PrinRLSMatrix(B); print(B); DestroySMatrix(A); DestroySMatrix(B); printf("\n\n");break; } printf("**********请选择是否继续输入其他稀疏矩阵? **********\n"); printf("1是,输入其他矩阵\n"); printf("0否,不输入\n"); printf("****************************************************"); fflush(stdin);//清除输入缓存区 scanf("%d",&j); }while(j==1); } 运行结果: (1)创建矩阵 (2)一般转置(3)快速转置 2、稀疏矩阵乘法、加法的算法(一般&十字链表) 代码: #include #include #defineSize2501 #defineSize151 typedefstruct { inti; intj; inte;//非零元的值 }triple;//定义三元组 typedefstruct { tripledata[Size+1];//矩阵中的元素 introps[Size1+1];//rops[i]为第i行元素中的首非零元在data[]中的序号 intmu;//行数 intnu;//列数 inttu;//非零元数 }juzhen;//定义矩阵 typedefstructnode//定义十字链表元素 { inti,j,e; structnode*right,*down;//该非零元所在行表和列表的后继元素 }node,*link; typedefstruct//定义十字链表对象结构体 { link*rhead,*chead;//行和列的头指针 intm,n,t;//系数矩阵的行数,列数,和非零元素个数 }crosslist; voidcreatecross(crosslist&M)//建立十字链表 { inti,j,e,k; node*p,*q; printf("输入行,列和非零元数,空格隔开: \n"); scanf("%d%d%d",&M.m,&M.n,&M.t); M.rhead=(link*)malloc((M.m+1)*sizeof(link));//给行和列的头指针分配存 M.chead=(link*)malloc((M.n+1)*sizeof(link)); for(k=1;k<=M.m;k++)//初始化行,列的头指针 M.rhead[k]=NULL; for(k=1;k<=M.n;k++) M.chead[k]=NULL; printf("输入非零元的行,列和值,空格隔开: \n"); for(k=1;k<=M.t;k++)//输入非零元 { scanf("%d%d%d",&i,&j,&e); p=(node*)malloc(sizeof(node)); p->i=i; p->j=j; p->e=e; if(M.rhead[i]==NULL||M.rhead[i]->j>j)//插入元素所在行无非零元或首非零元的列标大于插入元素的列标 { p->right=M.rhead[i]; M.rhead[i]=p; } else { for(q=M.rhead[i];(q->right)&&q->right->j p->right=q->right; q->right=p; } if(M.chead[j]==NULL||(M.chead[j]->i>i))//插入元素所在列无非零元或首非零元的行标大于插入元素的行标 { p->down=M.chead[j]; M.chead[j]=p; } else { for(q=M.chead[j];(q->down)&&q->down->idown);//空循环找到第一个行标大于或等于插入元素行标的元素 p->down=q->down; q->down=p; } } } voidprintcross(crosslistA)//输出十字链表 { if(A.m==0) printf("十字链表为空! \n"); else { printf("十字链表为: \n"); inti,j; for(i=1;i<=A.m;i++) { linkp=A.rhead[i]; for(j=1;j<=A.n;j++) { if((p)&&(j==p->j)) { printf("%5d",p->e); p=p->right;} else printf("%5d",0); } printf("\n"); } } printf("\n"); } crosslistaddcross() { printf("十字链表加法: \n"); crosslista,b;//创建两个十字链表对象,并初始化 createcross(a); createcross(b); node*pre,*h[51],*pa,*pb,*q;//定义辅助指针,pa,pb分别为a,b当前比较的元素,pre为pa的前驱元素 inti,j,k=0,m,n;//h[j]指向j列的当前插入位置 if(a.m! =b.m||a.n! =b.n) printf("格式不对,不能相加! \n"); else { for(i=1;i<=a.m;i++) { pa=a.rhead[i]; pb=b.rhead[i]; pre=NULL; for(j=1;j<=a.n;j++) h[j]=NULL; while(pb) { linkp; p=(node*)malloc(sizeof(node));//开辟新节点,存储b中取出的元素 p->i=pb->i; p->j=pb->j; p->e=pb->e; if(pa==NULL||pa->j>pb->j)//当a此行已经检查完或者pb因该放在pa前面 { if(pre==NULL) a.rhead[p->i]=p; else pre->right=p; p->right=pa; pre=p; if(h[p->j]==NULL)//当前插入位置下面无非零元 //因为是逐行处理,so,h[p->j],依次下移 //因此每次都是指向插入的位置 { a.chead[p->j]=p; p->down=NULL; } else { p->down=h[p->j]->down; h[p->j]->down=p; } h[p->j]=p;//*******h[p->j]下移指向下次插入的位置 pb=pb->right;//pb指向该行下个元素 } elseif((pa&&pa->j { pre=pa; h[pa->j]=pa;//移动h[],使其指向下次插入的位置 pa=pa->right; } elseif(pa->j==pb->j) { pa->e+=pb->e; if(pa->e)//不为零 { pre=pa; h[pa->j]=pa; pb=pb->right;//加 } else//pa->e为零,删除节点 { if(pre==NULL) a.rhead[pa->i]=pa->right; else { pre->right=pa->right; } p=pa;//p指向pa,用来在下面修改列指针 pa=pa->right; if(h[p->j]==NULL) a.chead[p->j]=p->down; else { h[p->j]->down=p->down; } free(p); pb=pb->right; } } } } } returna; } voidmultycross(crosslist&c)//十字链表乘法 { node*p,*q,*u,*v,*p1,*p2; crosslista,b; link*r; inti,j,k,e; printf("十字链表乘法: \n"); createcross(a); createcross(b); if(a.n! =b.m) printf("格式错误,不能相乘! \n"); else { c.m=a.m; c.n=b.n; c.t=0; c.rhead=(link*)malloc((a.m+1)*sizeof(link));//给行和列的头指针分配存 c.chead=(link*)malloc((b.n+1)*sizeof(link)); for(k=1;k<=a.m;k++)//初始化行,列的头指针 c.rhead[k]=NULL; for(k=1;k<=b.n;k++) c.chead[k]=NULL; r=(link*)malloc((b.n+1)*sizeof(link)); for(i=1;i<=a.m;i++) { u=(node*)malloc(sizeof(node)); u->e=0; u->i=0; u->j=0; for(k=1;k<=b.n;k++)//初始化r[] r[k]=u; p1=p=a.rhead[i]; for(j=1;j<=b.n;j++) { p=p1; q=b.chead[j]; v=(node*)malloc(sizeof(node));//初始化v,v为将插入c矩阵的元素
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数组 广义 算法 实验 报告