数据结构实验报告-数组和广义表

合集下载

数据结构数组与广义表

数据结构数组与广义表

/*稀疏矩阵转置:经典算法,二维数组存储方式*/#include<stdio.h>#include<stdlib.h>#define m6#define n7typedef int ElementType;/*算法5.1稀疏矩阵转置经典算法*/void TransMatrix(ElementType source[m][n],ElementType dest[n][m]){ int i,j;for(i=0;i<m;i++)for(j=0;j<n;j++)dest[j][i]=source[i][j];}/*T(n)=O(m*n),形参的S(n)=O(m*n)*/int main(void){int i,j;/*二维数组存储稀疏矩阵,初始化source矩阵*/ElementType source[m][n]={{0,12,9,0,0,0,0},{0,0,0,0,0,0,0},{-3,0,0,0,0,14,0},{0,0,24,0,0,0,0},{0,18,0,0,0,0,0},{15,0,0,-7,0,0,0}},dest[n][m];TransMatrix(source,dest);printf("被转置的矩阵:\n");for(i=0;i<m;i++){for(j=0;j<n;j++)printf("%4d",source[i][j]);printf("\n");}printf("转置后的矩阵:\n");for(i=0;i<n;i++){for(j=0;j<m;j++)printf("%4d",dest[i][j]);printf("\n");}return0;}/*稀疏矩阵转置:行列互换转置算法,三元组表存储方式*/#include<stdio.h>#include<stdlib.h>typedef int ElementType;#define MAXSIZE1000/*三元组表结点类型定义*/typedef struct{int row,col;/*行号、列号*/ElementType e;/*元素值*/}Triple;/*三元组表类型的定义*/typedef struct{Triple data[MAXSIZE+1];/*顺序表*/int m,n,len;/*行数、列数、非零元素个数*/}TSMatrix;/*稀疏矩阵行列互换转置算法*/void TransposeMatrix(TSMatrix A,TSMatrix*B){int i,j,k,p;Triple temp;/*临时结点*//*新的行数、列数、非零元素个数确定*/B->m=A.n;B->n=A.m;B->len=A.len;/*存在非零结点*/if(B->len>0){/*行列互换*/for(i=1;i<=A.len;i++){B->data[i].row=A.data[i].col;B->data[i].col=A.data[i].row;B->data[i].e=A.data[i].e;}/*三元组表B按行号排序,注意同号的次序不能打乱,不能用一般的排序方法*/k=1;/*B中将要确定的结点下标*/for(i=1;i<=B->m;i++)/*遍历每个行号,行号从1--b->m*/for(j=k;j<=B->len;j++)/*B中k-1以前的已处理*/if(i==B->data[j].row){/*找到结点*/temp=B->data[j];/*把找到的结点暂存*/for(p=j;p>k;p--)/*向后移动元素,空出位置k*/B->data[p]=B->data[p-1];B->data[k++]=temp;/*确定第k个结点,准备下一结点下标*/ }}}/*行列交换T(n)=O(A.len)最坏移动元素的次数:A.len(A.len-1)/2*/int main(void){int i,j,k;/*定义三元组表A、B,并初始化A*/TSMatrix A={0,0,0,/*0下标不结点使用*/1,2,12,1,3,9,3,1,-3,3,6,14,4,3,24,5,2,18,6,1,15,6,4,-7},B;A.m=6;A.n=7;A.len=8;/*调用函数实现转置*/TransposeMatrix(A,&B);/*输出三元组形式*/printf("三元组表A:\n");for(i=1;i<=A.len;i++)printf("%4d%4d%4d\n",A.data[i].row,A.data[i].col,A.data[i].e);printf("三元组表B:\n");for(i=1;i<=B.len;i++)printf("%4d%4d%4d\n",B.data[i].row,B.data[i].col,B.data[i].e);/*输出矩阵形式*/printf("三元组表A表示的稀疏矩阵:\n");k=1;/*三元组表的结点下标*/for(i=1;i<=A.m;i++){for(j=1;j<=A.n;j++)if(A.data[k].row==i&&A.data[k].col==j){printf("%4d",A.data[k].e);k++;}elseprintf("%4d",0);printf("\n");}printf("三元组表B表示的稀疏矩阵:\n");k=1;for(i=1;i<=B.m;i++){for(j=1;j<=B.n;j++)if(B.data[k].row==i&&B.data[k].col==j){printf("%4d",B.data[k].e);k++;}elseprintf("%4d",0);printf("\n");}return0;}/*稀疏矩阵转置:列序递增转置算法,三元组表存储方式*/ #include<stdio.h>#include<stdlib.h>typedef int ElementType;#define MAXSIZE1000/*三元组表结点类型定义*/typedef struct{int row,col;/*行号、列号*/ElementType e;/*元素值*/}Triple;/*三元组表类型的定义*/typedef struct{Triple data[MAXSIZE+1];/*顺序表*/int m,n,len;/*行数、列数、非零元素个数*/}TSMatrix;/*算法5.2稀疏矩阵列序递增转置算法*/void TransposeMatrix(TSMatrix A,TSMatrix*B){/*i--A的结点下标,j--B的结点下标,k--A的列序号*/int i,j,k;/*新的行数、列数、非零元素个数确定*/B->m=A.n;B->n=A.m;B->len=A.len;/*存在非零结点*/if(B->len>0){j=1;/*B的结点下标j从1开始*/for(k=1;k<=A.n;k++)/*列序递增:1--A.n*/for(i=1;i<=A.len;i++)/*每个列号k,扫描三元组表A的所有元素*/ if(k==A.data[i].col){/*找到了*/B->data[j].row=A.data[i].col;B->data[j].col=A.data[i].row;B->data[j].e=A.data[i].e;j++;/*B的下一个结点下标*/}}}/*T(n)=O(A.n*A.len)*/int main(void){int i,j,k;/*定义三元组表A、B,并初始化A*/TSMatrix A={0,0,0,/*0下标不结点使用*/1,2,12,1,3,9,3,1,-3,3,6,14,4,3,24,5,2,18,6,1,15,6,4,-7},B;A.m=6;A.n=7;A.len=8;/*调用函数实现转置*/TransposeMatrix(A,&B);/*输出三元组形式*/printf("三元组表A:\n");for(i=1;i<=A.len;i++)printf("%4d%4d%4d\n",A.data[i].row,A.data[i].col,A.data[i].e);printf("三元组表B:\n");for(i=1;i<=B.len;i++)printf("%4d%4d%4d\n",B.data[i].row,B.data[i].col,B.data[i].e);/*输出矩阵形式*/printf("三元组表A表示的稀疏矩阵:\n");k=1;/*三元组表的结点下标*/for(i=1;i<=A.m;i++){for(j=1;j<=A.n;j++)if(A.data[k].row==i&&A.data[k].col==j){printf("%4d",A.data[k].e);k++;}elseprintf("%4d",0);printf("\n");}printf("三元组表B表示的稀疏矩阵:\n");k=1;for(i=1;i<=B.m;i++){for(j=1;j<=B.n;j++)if(B.data[k].row==i&&B.data[k].col==j){printf("%4d",B.data[k].e);k++;}elseprintf("%4d",0);printf("\n");}return0;}/*稀疏矩阵转置:一次定位快速转置算法,三元组表存储方式*/ #include<stdio.h>#include<stdlib.h>typedef int ElementType;#define MAXSIZE1000/*三元组定义*/typedef struct{int row,col;/*行号、列号*/ElementType e;/*元素值*/}Triple;/*三元组表定义*/typedef struct{Triple data[MAXSIZE+1];/*顺序表*/int m,n,len;/*行数、列数、非零元素个数*/}TSMatrix;/*算法5.3稀疏矩阵一次定位快速转置算法*/void FastTransposeMatrix(TSMatrix A,TSMatrix*B){/*col--A的列号、B的行号,p--A的结点下标,q--B的结点下标*/int col,p,q;/*定义数组num[A.n+1],用于分别存储每列的非零元素个数*/int*num=(int*)malloc(sizeof(int)*(A.n+1));/*定义数组position[A.n+1],第col列第一个非零元素在B中的位置下标*/ int*position=(int*)malloc(sizeof(int)*(A.n+1));/*新的行数、列数、非零元素个数确定*/B->m=A.n;B->n=A.m;B->len=A.len;/*存在非零结点*/if(B->len>0){/*每列非零元素个数初始化为0*/for(col=1;col<=A.n;col++)num[col]=0;/*统计每列中非零元素的个数*/for(p=1;p<=A.len;p++)num[A.data[p].col]++;/*设置position[1]的值为1,第1列第一个非零元素在B的位置为1*/position[1]=1;/*确定第col列第一个非零元素在B的位置*/for(col=2;col<=A.n;col++)position[col]=position[col-1]+num[col-1];/*将被转置矩阵的三元组表A从头至尾扫描一次,实现矩阵转置*/for(p=1;p<=A.len;p++){col=A.data[p].col;/*所在列号*/q=position[col];/*在B存放的位置*/B->data[q].row=A.data[p].col;/*交换*/B->data[q].col=A.data[p].row;B->data[q].e=A.data[p].e;position[col]++;/*col列的下一个非零元素在B的位置*/ }}}/*f(n)=A.n+A.len+1+(A.n-1)+A.len=2(A.n+A.len),即T(n)=O(A.n+A.len)*/ /*S(n)=A.n+1+A.n+1=2(A.n+1),即S(n)=O(A.n)*/int main(void){int i,j,k;/*定义三元组表A、B,并初始化A*/TSMatrix A={0,0,0,/*0下标不结点使用*/1,2,12,1,3,9,3,1,-3,3,6,14,4,3,24,5,2,18,6,1,15,6,4,-7},B;A.m=6;A.n=7;A.len=8;/*调用函数实现转置*/FastTransposeMatrix(A,&B);/*输出三元组形式*/printf("三元组表A:\n");for(i=1;i<=A.len;i++)printf("%4d%4d%4d\n",A.data[i].row,A.data[i].col,A.data[i].e);printf("三元组表B:\n");for(i=1;i<=B.len;i++)printf("%4d%4d%4d\n",B.data[i].row,B.data[i].col,B.data[i].e);/*输出矩阵形式*/printf("三元组表A表示的稀疏矩阵:\n");k=1;/*三元组表的结点下标*/for(i=1;i<=A.m;i++){for(j=1;j<=A.n;j++)if(A.data[k].row==i&&A.data[k].col==j){printf("%4d",A.data[k].e);k++;}elseprintf("%4d",0);printf("\n");}printf("三元组表B表示的稀疏矩阵:\n");k=1;for(i=1;i<=B.m;i++){for(j=1;j<=B.n;j++)if(B.data[k].row==i&&B.data[k].col==j){printf("%4d",B.data[k].e);k++;}elseprintf("%4d",0);printf("\n");}return0;}/*稀疏矩阵转置:一次定位快速转置算法,三元组表存储方式*/#include<stdio.h>#include<stdlib.h>typedef int ElementType;/*十字链表的类型定义*//*非零元素结点的定义*/typedef struct OLNode{int row,col;/*非零元素:行号、列号、值*/ElementType value;struct OLNode*right;/*行后继链域、列后继链域*/struct OLNode*down;}OLNode,*OLink;/*OLNode结点类型、OLink指向结点的指针类型*//*十字链表的定义*/typedef struct{OLink*row_head;/*行头指针向量,二重指针,指向第0个行链指针*/ OLink*col_head;/*列头指针向量,二重指针,指向第0个列链指针*/ int m,n,len;/*稀疏矩阵的行数、列数、非零元素的个数*/}CrossList;/*十字链表类型*//*算法5.4创建十字链表*/void CreateCrossList(CrossList*M){int m,n,t;/*接收行数、列数、个数*/OLNode*p,*q;/*p指向新结点*/int i,j,e;/*接收结点的行号、列号、值*//*确定十字链表的成员m、n、len的值*/printf("输入M的行数、列数、非零元素的个数:\n");scanf("%d%d%d",&m,&n,&t);/*输入M的行数,列数和非零元素的个数*/ M->m=m;M->n=n;M->len=t;/*申请行列链指针分量,并确定row_head、col_head的值*//*申请m+1个行链指针分量,m+1个行链表*/if(!(M->row_head=(OLink*)malloc((m+1)*sizeof(OLink))))printf("error");/*申请n+1个列链指针分量,n+1个列链表*/if(!(M->col_head=(OLink*)malloc((n+1)*sizeof(OLink))))printf("error");/*把所有行列链指针置空*/for(i=1;i<=m;i++){M->row_head[i]=NULL;}for(i=1;i<=n;i++){M->col_head[i]=NULL;}/*链入结点*/printf("请输入非零结点行号、列号、值:(行号为0则结束输入)\n");for(scanf("%d%d%d",&i,&j,&e);i!=0;scanf("%d%d%d",&i,&j,&e)){ /*生成新结点*/if(!(p=(OLNode*)malloc(sizeof(OLNode))))printf("error");p->row=i;p->col=j;p->value=e;/*链入i行*/if(M->row_head[i]==NULL){/*是行中的第1个结点*/p->right=M->row_head[i];/*新结点尾置空*/M->row_head[i]=p;/*链接新结点*/}else{/*把q定位在第i行的未结点,利用空循环*/for(q=M->row_head[i];q->right&&q->right->col<j;q=q->right);p->right=q->right;/*新结点尾置空*/q->right=p;/*链接新结点*/}/*链入j列*/if(M->col_head[j]==NULL){/*是列中的第1个结点*/p->down=M->col_head[j];/*新结点尾置空*/M->col_head[j]=p;/*链接新结点*/}else{/*把q定位在第j行的未结点,利用空循环*/for(q=M->col_head[j];q->down&&q->down->row<i;q=q->down);p->down=q->down;/*新结点尾置空*/q->down=p;/*链接新结点*/}}}/*输出十字链表1*/void PrintCrossList(CrossList*M){int i,j;OLNode*p;for(i=1;i<=M->m;i++){/*以行为主输出*/p=M->row_head[i];/*行链起点*/for(j=1;j<=M->n;j++){if(p&&p->col==j){/*p存在且位于j列*/printf("%4d",p->value);p=p->right;/*链表下滑,不回溯*/}elseprintf("%4d",0);}printf("\n");}}/*输出十字链表2*/void out_Matrix(CrossList*M){int i,j;OLNode*p;for(i=1;i<=M->m;i++){/*以行为主输出*/for(j=1;j<=M->n;j++){p=M->row_head[i];/*每次均从本行头指针开始,p回溯*/while(p!=NULL){if(p->col==j)break;/*找到结点*/p=p->right;}if(p!=NULL)/*输出结点*/printf("%4d",p->value);elseprintf("%4d",0);}printf("\n");/*换行*/}}int main(void){CrossList M;CreateCrossList(&M);PrintCrossList(&M);out_Matrix(&M);return0;}/*广义表的头尾链表:头尾即表头、表尾的意思*/#include<stdio.h>#include<stdlib.h>#define AutoType int/*原子结点类型*//*结点分类:用枚举类型实现*/typedef enum{ATOM,LIST/*枚举值:值ATOM表示原子结点,值LIST表示子表*/ }ElemTag;/*ElemTag类型的变量仅有两个可取的枚举值*//*广义表结点类型的定义,广义表类型的定义*/typedef struct GLNOde{ElemTag tag;/*标志位tag用来区分原子结点和表结点*//*通过共用体实现广义表结点:要么是原子结点、要么是表结点*/ union{AutoType atom;struct{struct GLNode*hp,*tp;}htp;}atom_htp;}GLNode,*GList;int main(void){return0;}/*二维数组是“数据元素为一维数组”的线性表*//*即元素的类型是一种数据结构*/#include<stdio.h>#include<stdlib.h>#define M3#define N4#define ElementType int/*一维数组类型定义*/typedef struct{ElementType data[N];/*N个数据元素为ElementType的顺序表*/ }Array;/*新的数据类型为Array*/int main(void){Array A[M];/*M个数据类型为Array的顺序表*/int i,j;/*随机输入矩阵的值*/for(i=0;i<M;i++)for(j=0;j<N;j++)A[i].data[j]=rand()%100;/*范围0--99*//*输出矩阵的值*/for(i=0;i<M;i++){for(j=0;j<N;j++)printf("%4d",A[i].data[j]);printf("\n");}return0;}/*一维数组的顺序存储*/#include<stdio.h>#include<stdlib.h>int main(void){int a[10];/*顺序存储*/printf("a[0]的地址:%d\n",&a[0]);printf("a[5]的地址(内部实现):%d\n",&a[5]);/*Loc(a[i])=Loc(a[0])+(i-0)*size*//*Loc(a[i])=Loc(a[0])+(i)*size*//*size自动分配,例如+5,地址实质上增大了20*/printf("a[5]的地址(公式计算):%d\n",&a[0]+5);return0;}/*二维数组的顺序存储*/#include<stdio.h>#include<stdlib.h>int main(void){int a[5][4];/*以行为主的顺序存储,m=5行n=4列*/printf("a[0][0]的地址:%d\n",&a[0][0]);printf("a[3][2]的地址(内部实现):%d\n",&a[3][2]);/*Loc(a[i][j])=Loc(a[0][0])+((i-0)*n+(j-0))*size*//*Loc(a[i][j])=Loc(a[0][0])+(i*n+j)*size*/printf("a[3][2]的地址(公式计算):%d\n",&a[0][0]+3*4+2);return0;}/*三维数组的顺序存储*/#include<stdio.h>#include<stdlib.h>int main(void){int a[5][4][6];/*以行为主的顺序存储,m=5行n=4列r=6纵*/printf("a[0][0][0]的地址:%d\n",&a[0][0][0]);printf("a[3][2][4]的地址(内部实现):%d\n",&a[3][2][4]);/*Loc(a[i][j][k])=Loc(a[0][0][0])+((i-0)*n*r+(j-0)*r+(k-1))*size*//*Loc(a[i][j][k])=Loc(a[0][0][0])+(i*n*r+j*r+k)*size*/printf("a[3][2][4]]的地址(公式计算):%d\n",&a[0][0][0]+3*4*6+2*6+4);return0;}/*三角矩阵的压缩存储*/#include<stdio.h>#include<stdlib.h>#define ElementType int#define MAXSIZE1000/*矩阵的压缩类型定义*/typedef struct{ElementType data[MAXSIZE+1];/*非0元素的空间,data[0]未用*/int n,len;/*n为矩阵的阶数,即n*n矩阵;len非0元素的个数*/ }Matrix;int main(void){int i,j;/*下三角矩阵变量A的定义及初始化*/Matrix A={0,/*未用*/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};A.n=5;/*阶数n*/A.len=A.n*(A.n+1)/2;/*输出下三角矩阵*/for(i=1;i<=A.n;i++){for(j=1;j<=A.n;j++)if(i<j)printf("%4d",0);else/*下标从1考虑,第几个元素的下标就是几*/printf("%4d",A.data[i*(i-1)/2+j]);printf("\n");}return0;}/*三对角带状矩阵的压缩存储*/#include<stdio.h>#include<stdlib.h>#define ElementType int#define MAXSIZE1000/*矩阵的压缩类型定义*/typedef struct{ElementType data[MAXSIZE+1];/*非0元素的空间,data[0]未用*/int n,len;/*n为矩阵的阶数,即n*n矩阵;len非0元素的个数*/ }Matrix;int main(void){int i,j;/*三对角带状矩阵变量A的定义及初始化*/Matrix A={0,/*未用*/1,2,2,3,4,3,4,5,4,5,6,5,6};A.n=5;/*阶数n*/A.len=3*A.n-2;/*输出三对角带状矩阵*/for(i=1;i<=A.n;i++){for(j=1;j<=A.n;j++)if(j==i-1||j==i||j==i+1)/*三对角带状条件*/printf("%4d",A.data[2*(i-1)+j]);elseprintf("%4d",0);printf("\n");}return0;}。

数据结构-第五章 数组与广义表-文档资料

数据结构-第五章 数组与广义表-文档资料

上 三 角 矩 阵 下 三 角 矩 阵
a00 a10 a 20 an10
0 1 2
a01 a11 a21 an11
3 4
a02 a12 a22 an12
5

6 7
a0 n1 a1n1 a2 n1 an1n1
行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
用三元组表表示的稀疏矩阵及其转置
行 列 值 (row) (col) (value) 0 3 22 0 6 15 1 1 11 1 5 17 2 3 -6 3 5 39 4 0 91 5 2 28 行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
4 5 6 7 8 9 10
B a00 a01 a10 a11 a12 a21 a22 a23 … an-1n-2 an-1n-1
三对角矩阵中除主对角线及在主对角线上 下最临 近的两条对角线上的元素外,所有其它元素均为 0。总共有3n-2个非零元素。 将三对角矩阵A中三条对角线上的元素按行存放在 一维数组 B 中,且a00存放于B[0]。 在三条对角线上的元素aij 满足 0 i n-1, i-1 j i+1 在一维数组 B 中 A[i][j] 在第 i 行,它前面有 3*i-1 个非零元素, 在本行中第 j 列前面有 j-i+1 个,所 以元素 A[i][j] 在 B 中位置为 k = 2*i + j。
三对角矩阵的压缩存储

数据结构:第5章 数组与广义表1-数组

数据结构:第5章 数组与广义表1-数组

中的元素均为常数。下三角矩阵正好相反,它的主对
数据结构讲义
第5章 数组与广义表
—数组
数组和广义表
数组和广义表可看成是一种特殊的 线性表,其特殊在于,表中的数据 元素本身也是一种线性表。
几乎所有的程序设计语言都有数组 类型。本节重点讲解稀疏矩阵的实 现。
5.1 数组的定义
由于数组中各元素具有统一的类型,并且 数组元素的下标一般具有固定的上界和下 界,因此,数组的处理比其它复杂的结构 更为简单。
nm
aa1221
aa2222
…………....
aam2n2 ………………..
aamm11 aamm22 ………….... aammnn LLoocc(a( iaj)ij=)L=Loco(ca(a111)1+)[+([j(-i1-)1m)n++((i-j1-1)])*]*l l
aa1mn 1 aa2mn2 …………....
其存储形式如图所示:
15137 50800 18926 30251
a00 a10 a 11 a20 a21 a23 ………………..
70613
an-1 0 a n-1 1 a n-1 2 …a n-1 n-1
图 5.1 对称矩阵
在这个下三角矩阵中,第i行恰有i+1个元素,元素总
数为:
n(n+1)/2
5.2 数组的顺序表示和实现
由于计算机的内存结构是一维的,因此用 一维内存来表示多维数组,就必须按某种 次序将数组元素排成一列序列,然后将这 个线性序列存放在存储器中。
又由于对数组一般不做插入和删除操作, 也就是说,数组一旦建立,结构中的元素 个数和元素间的关系就不再发生变化。因 此,一般都是采用顺序存储的方法来表示 数组。

数组与广义表的算法的实验报告

数组与广义表的算法的实验报告

数组与广义表的算法实验工具:visual C++实验内容:1、三元组表示稀疏矩阵的转置算法(一般&快速)<1-7页> 2、稀疏矩阵乘法、加法的算法(一般&十字链表)<8-21页> 3、广义表的各种算法<22-28页> 体验:通过利用visual C++实验工具,实现数组与广义表各类算法的过程中,本人对数组与广义表的知识有了更深的了解,而且认识到数组与广义表各类操作可由形式多样的算法结构实现。

算法并非统一标准的,同样的结果可有多种算法得出,算法的编写鼓励创造性思维。

1、三元组表示稀疏矩阵的转置算法(一般&快速)代码:#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<windows.h>#define OK 1#define ERROR 0#define OVERFLOW 0#define MAXSIZE 100#define MAXRC 100typedef int ElemType;typedef struct{int i,j;ElemType e;}Triple;typedef struct{Triple data[MAXSIZE+1]; //非零元三元组int rpos[MAXRC+1]; //各行第一个非零元的位置表int mu,nu,tu; //矩阵的行数、列数和非零元个数}RLSMatrix;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);}void DestroySMatrix(RLSMatrix &M) //销毁稀疏矩阵M{M.mu=0;M.nu=0;M.tu=0;}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");}void print(RLSMatrix A) //打印矩阵函数,以通常形式输出矩阵{int k=1,a,b;printf("稀疏矩阵的通常形式为:\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");}}void showtip() //菜单{printf(" ********************请选择要执行的操作********************\n\n");printf(" & 1 采用一般算法实现&\n");printf(" & 2 采用快速转置的算法实现&\n");printf(" & 3 同时采用两种算法,先显示一般算法,再显示快速算法&\n");printf(" **********************************************************\n\n");}////头文件结束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;}FastTransposeSMatrix(RLSMatrix M,RLSMatrix &T) //快速转置算法{int p,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);return OK;}void main(){int result;int j;RLSMatrix A,B;//************************************************COORD Co={0,0};DWORD Write;SetConsoleTitle("稀疏矩阵的转置\n");HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTextAttribute(hOut,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND _INTENSITY);FillConsoleOutputAttribute(hOut,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROU ND_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);PrinRLSMatrix(A);printf("求A的转置矩阵B(一般算法):\n");TransposeSMatrix(A,B);PrinRLSMatrix(B);print(B);DestroySMatrix(B);printf("\n\n");break;case 2: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;case 3: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<stdio.h>#include<malloc.h>#define Size 2501# define Size1 51typedef struct{int i;int j;int e;//非零元的值}triple; //定义三元组typedef struct{triple data[Size+1];//矩阵中的元素int rops[Size1+1];// rops[i]为第i行元素中的首非零元在data[]中的序号int mu;//行数int nu;//列数int tu;//非零元数} juzhen;//定义矩阵typedef struct node// 定义十字链表元素{int i,j,e;struct node *right,*down;// 该非零元所在行表和列表的后继元素}node,*link;typedef struct // 定义十字链表对象结构体{link *rhead,*chead;//行和列的头指针int m,n,t;// 系数矩阵的行数,列数,和非零元素个数}crosslist;void createcross(crosslist &M)//建立十字链表{int i,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<j;q=q->right);//空循环找到第一个列标大于或等于插入元素列标的元素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->i<i;q=q->down);//空循环找到第一个行标大于或等于插入元素行标的元素p->down=q->down;q->down=p;}}}void printcross(crosslist A)//输出十字链表{if(A.m==0)printf("十字链表为空!\n");else{printf("十字链表为:\n");int i,j;for(i=1;i<=A.m;i++){link p=A.rhead[i];for(j=1;j<=A.n;j++){if((p)&&(j==p->j)){printf("%5d",p->e);p=p->right; }elseprintf("%5d",0);}printf("\n");}}printf("\n");}crosslist addcross(){printf("十字链表加法:\n");crosslist a,b;// 创建两个十字链表对象,并初始化createcross(a);createcross(b);node *pre,*h[51],*pa,*pb,*q;//定义辅助指针,pa,pb分别为a,b当前比较的元素,pre为pa的前驱元素int i,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){link p;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;elsepre->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指向该行下个元素}else if((pa&&pa->j<pb->j))//只要移动pa的指针****先不加||(pb==NULL&&pa){pre = pa;h[pa->j]=pa;//移动h[],使其指向下次插入的位置pa = pa->right;}else if(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;}}}}}return a;}void multycross(crosslist &c)//十字链表乘法{node *p,*q,*u,*v,*p1,*p2;crosslist a,b;link *r;int i,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矩阵的元素v->e=0;v->i=i;v->j=j;while(p&&q){if(p->j>q->i)q=q->down;else if(p->j<q->i)p=p->right;else{v->e+=p->e*q->e;p=p->right;q=q->down;}}if(v->e)//如果不为零,则插入c矩阵中{//同建立十字链表if(c.rhead[i]==NULL||c.rhead[i]->j>j)//插入元素所在行无非零元或首非零元的列标大于插入元素的列标{v->right=c.rhead[i];c.rhead[i]=v;}else{for(p2=c.rhead[i];(p2->right)&&(p2->right->j<j);p2=p2->right);//空循环找到第一个列标大于或等于插入元素列标的元素v->right=p2->right;p2->right=v;}if(c.chead[j]==NULL||c.chead[j]->i>i)//插入元素所在列无非零元或首非零元的行标大于插入元素的行标{v->down=c.chead[j];c.chead[j]=v;}else{for(p2=c.chead[j];(p2->down)&&(p2->down->i<i);p2=p2->down);//空循环找到第一个行标大于或等于插入元素行标的元素v->down=p2->down;p2->down=v;}}}}}}void create(juzhen & M) //创建稀疏矩阵{int i,t=0;printf("输入矩阵行数和列数and非零元的个数,以空格隔开:\n");scanf("%d %d %d",&M.mu,&M.nu,&M.tu);printf("输入矩阵非零元的行,列,和数值(中间空格隔开):\n");for(i=1;i<=M.tu;i++)scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e); //输入三元组的元素 for(i=1;i<=Size1;i++)//初始化rops【】M.rops[i]=0;for(i=1,t=1;i<=M.mu;i++)//得到各行第一个元素的序号{M.rops[i]=t;while(M.data[t].i<=i&&t<=M.tu)//遇到i行非零元,则t累加t++;}}void add(juzhen A,juzhen B,juzhen & C)//稀疏矩阵加法{int k=1,temp=0,k1=1, k2=1;//k1,k2,k分别控制A,B,C中非零元的序号变化printf("稀疏矩阵加法:\n");create(A);create(B);if(A.mu!=B.mu||A.nu!=B.nu)printf("格式不对,不能相加!\n");else{while(k1<=A.tu&&k2<=B.tu)//当A,B中的非零元都没用完{if(A.data[k1].i<B.data[k2].i)//A当前k1指向的元素的行标小于列标直接把data【k1】的值赋给c中data【k】C.data[k++]=A.data[k1++];else if(A.data[k1].i>B.data[k2].i)//同上C.data[k++]=B.data[k2++];else//data[k1],data[k2]行标相同{if(A.data[k1].j>B.data[k2].j)//data[k1]列标大于data[k2]列标,则把data[k2]的值赋给data[k]C.data[k++]=B.data[k2++];else if(A.data[k1].j<B.data[k2].j)//同上C.data[k++]=A.data[k1++];else //行,列标都相同{temp=0;temp=A.data[k1].e+B.data[k2].e;if(temp)//相加后不为零{C.data[k].i=A.data[k1].i;C.data[k].j=A.data[k1].j;C.data[k].e=temp;k++;}k1++;k2++;}}}while(k1<=A.tu)//B中非零元已用完,A中还有非零元C.data[k++]=A.data[k1++];while(k2<=B.tu)//A中非零元已用完,B中还有非零元C.data[k++]=B.data[k2++];C.mu=A.mu;//确定C的行列数和非零元个数C.nu=A.nu;C.tu=k-1;}}void print(juzhen A)//输出稀疏矩阵{printf("\n矩阵为:\n");int i,j,k=1;if(A.mu==0)printf("矩阵为空!\n");else if(A.tu==0)//矩阵元素为空printf("零矩阵!\n");elsefor(i=1;i<=A.mu;i++)//逐行输出{for(j=1;j<=A.nu;j++){if(A.data[k].i==i&&A.data[k].j==j)//行和列分别对应相等则输出相应非零元,否则输出零printf("%5d",A.data[k++].e);elseprintf("%5d",0);}printf("\n");//该行输出结束,空行输出下一行}printf("\n");}void multy(juzhen A,juzhen B,juzhen &C)//稀疏矩阵乘法{int arow,brow,ccol,temp[51],p,q,t,tp,i;//各变量代表含义见下面printf("稀疏矩阵乘法:\n");create(A);create(B);if(A.nu!=B.mu)printf("格式错误,不能相乘!\n");else{C.mu=A.mu;//初始化c的行列及非零元个数C.nu=B.nu;C.tu=0;if(A.nu!=B.mu)printf("A,B格式不对不能相乘!\n");else //{for(arow=1;arow<=A.mu;arow++)//arow为当前A矩阵的行标{for(i=0;i<51;i++)//初始化temptemp[i]=0;if(arow<A.mu)tp=A.rops[arow+1];//tp为arow+1行的首非零元在data【】中的序号else //arow为最后一行tp=A.tu+1;for(p=A.rops[arow];p<tp;p++)//p为A中当前元素在data[]中的序号{brow=A.data[p].j;//brow为与B矩阵中的相应行对应的A中当前元素的列标if(brow<B.mu)t=B.rops[brow+1];//t为brow+1行的首非零元在B中data 【】中的序号else //brow大小等于B.mut=B.tu+1;for(q=B.rops[brow];q<t;q++)//q为B中当前元素在B.data[]中的序号{ccol=B.data[q].j;//ccol:data[p]*data[q]所得结果所在的列temp[ccol]+=A.data[p].e*B.data[q].e;//temp【ccol】:相乘所得的C矩阵中第arow行cool列元素的值}}for(ccol=1;ccol<=B.nu;ccol++)//if(temp[ccol])//temp【ccol】不为零,则把值赋到c中,c.tu加1。

《数据结构——用C语言描述(第二版)》第5章 数组和广义表

《数据结构——用C语言描述(第二版)》第5章  数组和广义表
是指矩阵的下三角(不含对角线)中的元素均为常数C或零的n阶矩阵,下 三角矩阵则与之相反,如图5.3所示。
第五章 数组和广义表
在压缩存储时,矩阵中值相同的元素C可共享一个存储空间,元素 为零则可不必分配空间,而其余的元素有 n(n+1)/2个,因此三角矩阵 可用一维数组M[n×(n+1)/2+1]来存储,其中常数C放在数组的最后一 个下标变量中。
假设A和B矩阵分别用matrix型指针变量a和b表示,矩阵的转置可以 按以下进行:由于B的行是A的列,所以可按照b->data三元组表的次序在 a->data中找到相应的三元组进行转置,即可按a->data的列序转置,所得 到的转置矩阵B的三元组表b->data必定是按行优先存放的。因此,可以对 三元组表a->data从第一行起扫描,找到A的每一列中所有的非零元素,就 可以实现转置。
LOC ( aij ) =LOC ( a00) +(i×n+j) × c 同理可推导出以列为主序优先存储时数据元素a i j 的存储地址,其计算公式 为:
LOC( a i j ) =LOC( a00 ) +( j × n +i ) × c 对于三维数组Am×n×p而言,若以行为主序优先存储时,则其数据元 素aijk的存储地址可为: LOC ( a i j k) =LOC ( a000) +[ i × m×p +j ×p +k] × c 对于一般的二维数组A[c1…d1,c2…d2]而言,此处c1,c2的值不一定是 0,a i j 的地址为: LOC ( a i j ) =LOC ( a c 1 c 2 ) +[ ( i – c 1 )* ( d 2 – c 2 +1) +j – c 2 ] * c

数据结构实验报告_9

数据结构实验报告_9

本科生实验报告(二)姓名:学院:专业:班级:实验课程名称: 数据结构实验日期: 2013年 5月 25 日指导教师及职称:实验成绩:开课时间:2012~2013 学年第二学期k++;a[j][n-i-1]=k;}for (j=n-i-2;j>=i;j--){k++;a[n-i-1][j]=k;}for (j=n-i-2;j>=i+1;j--){k++;[j][i]=k;}}}void main(){int n,i,j;int a[MaxLen][MaxLen];printf("输入n(n<10):");scanf("%d",&n);fun(a,n);printf("%d阶数字方阵如下:\n",n);for (i=0;i<n;i++){for (j=0;j<n;j++)printf("%4d",a[i][j]);printf("\n");}}运行结果:6.2:如果矩阵A中存在这样的一个元素A[i][j]满足条件:A[i][j]是第i行中值最小的元素,且又是第j列中值最大的元素,则称为该矩阵的一个马鞍点。

设计一个程序exp6-2.cpp 计算出m*n的矩阵A的所有马鞍点。

主程序如下:6.3:已知A和B为两个n*n阶的对称矩阵,输入时,对称矩阵只输入下三角形元素,存入一维数组,如图6.5所示(对称矩阵M存储在一维数组A中),设计一个程序exp6-3.cpp 实习如下功能:(1)求对称矩阵A和B的和。

(2)求对称矩阵A和B的乘积。

A:图6.5 对称矩阵的存储转换形式主程序如下:#include <stdio.h>#define N 4#define M 10int value(int a[],int i,int j){if (i>=j)return a[(i*(i-1))/2+j];elsereturn a[(j*(j-1))/2+i];}void madd(int a[],int b[],int c[][N]){int i,j;for (i=0;i<N;i++)printf("a+b:\n");disp2(c1);printf("a×b:\n");disp2(c2);printf("\n");}运行结果:6.4::假设n*n的稀疏矩阵A采用三元组表示,设计一个程序exp6-4.cpp实现如下功能:(1)生成如下两个稀疏矩阵矩阵的三元组a和b:(2)输出a转置矩阵的三元组;(3)输出a+b的三元组;(4)输出a*b的三元组。

数组和广义表 数据结构

数组和广义表  数据结构

3.建立广义表的存储结构 假定广义表中的元素类型ElemType为chai类型,每个原子的值被限 定为英文字母。并假定广义表是一个表达式,其格式为:元素之间用一 个逗号分隔,表元素的起止符号分别为左、右圆括号,空表在其圆括号 内不包含任何字符。例如“(a,(b, c, d))”就是一个符合上述规定的广 义表格式。 建立广义表存储结构的算法同样是一个递归算法。该算法使用一个 具有广义表格式的字符串参数s,返回由它生成的广义表存储结构的头结 点指针h。在算法的执行过程中,需要从头到尾扫描s的每一个字符。当 碰到左括号时,表明它是一个表元素的开始,则应建立一个由h指向的表 结点,并用它的sublist域作为子表的表头指针进行递归调用,来建立子 表的存储结构;当碰到一个英文字母时,表明它是一个原子,则应建立 一个由h指向的原子结点;当碰到一个“)”字符时,表明它是一个空表, 则应置h为空。当建立了一个由h指向的结点后,接着碰到逗号字符时, 表明存在后继结点,需要建立当前结点(即由h指向的结点)的后继表; 当碰到右括号或分号字符时,表明当前所处理的表已结束,应该置当前 结点的link域为空。 4.输出广义表 5.广义表的复制
广义表的转换过程
为了使子表和原子两类结点既能在形式上保持一致,又能进
行区别,可采用如下结构形式:
其中,tag域为标志字段,用于区分两类结点。sublist或data
域由tag决定。若tag=0,表示该结点为原子结点,则第二个 域为data,存放相应原子元素的信息;若tag=l,表示该结点 为表结点,则第二个域为sublist,存放相应子表第一个元素 对应结点的地址。link域存放与本元素同一层的下一个元素所 在结点的地址,当本元素是所在层的最后一个元素时,link域 为NULL。 例:前面的广义表C的存储结构如下图所示(很多《数据结构 公教科书上称之为带表头结点的广义表的链表存储结构

数据结构Ch数组和广义表

数据结构Ch数组和广义表
//O(n)
✓ step4:扫描a.data,将(i,col,v)转置后放于b.data[pot[col]] 中,pot[col]++. //O(t)
时间O(n+t),快速。
key:pot[1..a.n]=第0~a.n-1列的非零元个数。
20
§5.2 矩阵的压缩存储
void FastTransMatrix(TripleTable &a , Tripletable &b) {//pot[0..a.n],比n多1 if (a.t == 0) Error(“…”);//A全零
11
§5.2 矩阵的压缩存储
3. 对角矩阵
总结:这类矩阵压缩存储后能找到地址计算公式, 使其保持随机存取的功能。
12
§5.2 矩阵的压缩存储
§ 5.2.2 稀疏矩阵
定义:设Amn中有t个非零元素,若 稀疏矩阵。
,称A为
稀疏因子: 压缩存储:
一般非零元素分布无规律性
只存储非零元,故须存储辅助信息,才能确 定其位置。
b.data[q].v = a.data[p].v;
}
}
21
§5.2 矩阵的压缩存储
以上图为例,
2. 带行表的三元组表。(顺序方式)
在行优先存储的三元组表中,加入一个行
表来记录稀疏矩阵压缩后每行非零元在三元组表
中的起始位置。
22
§5.2 矩阵的压缩存储
3. 十字链表 上两种方式是顺序存储,若非零元位置或个数经常发生 变化,会引起结点移动,效率降低。此时宜用链式存储。 例:A←A+B 稀疏矩阵的链接存储方式有多种,这里仅介绍十字链表
2
§5.1 多维数组
非线性特征 i th行:前驱aij-1,后继aij+1 j th列:前驱ai-1j,后继ai-1j 仅有一个开始结点:a11 仅有一个终端节点:amn 其他边界上的结点只有一个直接前驱或 一个直接后继,类似的m维数组 的 每一个元素都属于m个向量。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《数据结构》实验报告
实验序号: 7实验项目名称:数组和广义表
学号姓名专业班级
实验地点指导教师实验时间
一、实验目的及要求
本次实验目的是通过上机练习,熟悉和掌握课堂所讲授的基本知识点。

要求
上机以前要认真复习课堂教学内容。

完成稀疏矩阵的三元组顺序存储。

二、实验设备(环境)及要求
计算机;学生不许把食物带到机房吃;不许上网做与实验无关的内容;不许
同学之间聊天;保持实验室安静卫生。

下课把键盘,座椅放回原处。

三、实验内容与步骤
稀疏矩阵压缩存储,三元组顺序表的实现。

然后完成操作CreateSMatrix(&M) 创建稀疏矩阵,和求稀疏矩阵的转置 TransposeSMatrix(TSMatrix &M, TSMatrix &T) 。

编写一个函数,按照矩阵的形式打印出稀疏矩阵。

Header.h
#include<stdio.h>
#include<stdlib.h>
//稀疏矩阵的三元组顺序表存储
#define MAXSIZE 125 //非零元个数的最大值
typedef int ElemType;
typedef struct//三元组节点
{
int i,j;//非零元的行下标、列下标
ElemType e;//矩阵的元素值。

}Triple;
typedef struct
{
Triple data[MAXSIZE+1];//非零元数组,data[0]不用。

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

}TSMatrix;
//-------稀疏矩阵的操作函数-------//
void CreateSMatrix(TSMatrix *M)
//以行为主序,创建稀疏矩阵
{
char sign='y';
int tu;
(*M).tu=0;(*M).mu=0;(*M).nu=0;
printf("请输入矩阵的行数: \n");
scanf("%d",&(*M).mu);
printf("请输入矩阵的列数: \n");
scanf("%d",&(*M).nu);
while(sign=='y')
{
++(*M).tu;
tu=(*M).tu;
printf(" 请输入第 %d个非零元 \n",tu);
printf("\n请输入行号: ");
scanf("%d",&(*M).data[tu].i);
printf("\n请输入列号: ");
scanf("%d",&(*M).data[tu].j);
printf("\n请输入元素值: ");
scanf("%d",&(*M).data[tu].e);
printf("\n\n如果继续输入其他非零元素,请输入字母'y' ,否则请输入 'n' : ");
scanf("%c%c",&sign,&sign);
}
}
void PrintSMatrix(TSMatrix *M)
{
int *p,k,i,j;
int mu,nu,tu;
mu=(*M).mu;nu=(*M).nu;tu=(*M).tu;
p=(int *)malloc((nu+1)*sizeof(ElemType));//用来保存每行元素。

for(i=1;i<=mu;i++)
{
for(k=0;k<=nu;k++) p[k]=0;
for(k=1;k<=tu;k++)
{
if((*M).data[k].i==i)
p[(*M).data[k].j]=(*M).data[k].e;
}
for(j=1;j<=nu;j++) printf("%-5d",p[j]);
printf("\n");
}
}
void TransposeSMatrix(TSMatrix *M,TSMatrix *T) //采用三元组表存储,实现稀疏矩阵的转置。

{
int q=1,col=1;
(*T).mu=(*M).nu;
(*T).nu=(*M).mu;
(*T).tu=(*M).tu;
for(col=1;col<=(*M).nu;col++)
{
for(q=1;q<=(*M).tu;q++)
if((*M).data[q].j==col)
{
(*T).data[q].i=(*M).data[q].j;
(*T).data[q].j=(*M).data[q].i;
(*T).data[q].e=(*M).data[q].e; }
}
}
Source.h
#include"header.h"
void main()
{
TSMatrix M,T;
CreateSMatrix(&M); PrintSMatrix(&M); TransposeSMatrix(&M,&T); printf("\n\n");
PrintSMatrix(&T);
四、实验结果与数据处理
五、分析与讨论
以前学过另一种将矩阵转置的方法,现在学习的这种方法更方便,遇到复杂、阶数比较大的有规律的矩阵,存储更省内存。

这种方法更具有一般性,能学到这种通用的方法大大减轻了计算量,感觉很好。

六、教师评语成绩
签名:
日期:。

相关文档
最新文档