数据结构实践-第6周 串数组和广义表(设计)

合集下载

数据结构串、数组和广义表知识点总结

数据结构串、数组和广义表知识点总结

数据结构串、数组和广义表知识点总结
数据结构是计算机科学中研究数据如何组织、存储、管理和操作的学科。

三个常见的数据结构串、数组和广义表都是用于存储和操作数据的。

1. 串:
- 串是由0个或多个字符组成的有限序列。

它是一维数组的特例。

- 串的操作包括插入、删除、修改和查找等常见操作。

- 串可以通过数组、链表或动态分配的内存来实现。

2. 数组:
- 数组是一种线性数据结构,它由一组连续的内存空间组成,
存储相同类型的数据。

- 数组的操作包括插入、删除、修改和查找等常见操作。

- 数组的访问时间复杂度为O(1),但插入和删除的时间复杂度
较高。

3. 广义表:
- 广义表是由若干元素组成的有序集合,每个元素可以是原子
或者是一个广义表。

- 广义表可以通过链表来实现,每个节点包含两个指针,一个
指向元素,一个指向下一个节点。

- 广义表的操作包括插入、删除、修改和查找等常见操作。

- 广义表可以表示任意层次的嵌套结构,具有灵活性和扩展性。

总结:
- 串、数组和广义表都是常见的数据结构,用于存储和操作数据。

- 串是字符的有限序列,可以通过数组或链表来实现。

- 数组是一维线性数据结构,存储相同类型的数据,具有常数时间复杂度的访问操作。

- 广义表是由元素组成的有序集合,可以通过链表来实现,能够表示任意层次的嵌套结构。

数据结构数组与广义表

数据结构数组与广义表

/*稀疏矩阵转置:经典算法,二维数组存储方式*/#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;}。

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

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

数组与广义表的算法实验工具: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。

李春葆《数据结构教程》(第4版)章节题库-数组和广义表(圣才出品)

李春葆《数据结构教程》(第4版)章节题库-数组和广义表(圣才出品)

第6章数组和广义表一、选择题1.设有一个10阶的对称矩阵A,采用压缩存储方式,以行序为主存储,a11为第一元素,其存储地址为1,每个元素占一个地址空间,则a85的地址为()。

A.13B.33C.18D.40【答案】B【解析】对于对称矩阵,a i,j=a j,i。

为了节省存储空间,为多个相同的元素只分配一个存储空间。

对于对称矩阵,元素下表之间的对应关系为:当i>=j时,k=i(i-1)/2+j -1;当i< =j 时,k=j(j-1)/2+i-1。

其中k相当于地址空间的标号,i为行号,j为列号。

因为第一个元素存储地址为1,所以最后计算的k需要加1。

所以a85的存储位置为8*(8-1)/2+5=33。

2.设有数组A[i,j],数组的每个元素长度为3字节,i的值为1到8,j的值为1到10,数组从内存首地址BA开始顺序存放,当用以列为主存放时,元素A[5,8]的存储首地址为()。

A.BA+141B.BA+180C.BA+222D.BA+225【答案】B【解析】在计算中,可以考虑按照列存放时,A[5,8]在内存的位置,比较容易计算元素的首地址。

比如A[5,8]顺序存放时,它是第7*8+5=61个元素,由于首地址为BA,所以它的存储首地址为BA+(61-1)*3=180+BA。

3.数组通常具有的两种基本操作是()。

A.查找和修改B.查找和索引C.索引和修改D.建立和删除【答案】A【解析】数组中的元素是顺序存放的,通过下标可以很好地查找数组元素,同时通过对应的指针可以修改数组元素的值,因此数组通常具有的两种基本操作是查找和修改。

根据数组的性质,数组通常具有的两种基本运算是排序和查找。

4.将一个A[1..100,1..100]的三对角矩阵,按行优先存入一维数组B[1..298]中,A中元素A6665(即该元素下标i=66,j=65),在B数组中的位置K为()。

A.198B.195C.197【答案】B【解析】将对角矩阵a[i][j]存入b[k],三对角矩阵压缩地址计算公式如下:k=2i+j-2。

数据结构教程李春葆课后答案第6章数组和广义表

数据结构教程李春葆课后答案第6章数组和广义表

3. 如果某个一维数组 A 的元素个数 n 很大,存在大量重复的元素,且所有元素值相同 的元素紧挨在一起,请设计一种压缩存储方式使得存储空间更节省。
答:设数组的元素类型为 ElemType,采用一种结构体数组 B 来实现压缩存储,该结构 体数组的元素类型如下:
struct { ElemType data;
解:从二维数组 B 的右上角的元素开始比较。每次比较有三种可能的结果:若相等, 则比较结束;若 x 大于右上角元素,则可断定二维数组的最上面一行肯定没有与 x 相等的 数据,下次比较时搜索范围可减少一行;若 x 小于右上角元素,则可断定二维数组的最右 面一列肯定不包含与 x 相等的数据,下次比较时可把最右一列剔除出搜索范围。这样,每 次比较可使搜索范围减少一行或一列,最多经过 m+n 次比较就可找到要求的与 x 相等的元 素。对应的程序如下:
{ printf("不是对角矩阵\n");
return false;
}
for (int i=0;i<a.nums;i++)
if (a.data[i].r==a.data[i].c) //行号等于列号
sum+=a.data[i].d;
return true;
}
11. 设计一个算法 Same(g1,g2),判断两个广义表 g1 和 g2 是否相同。 解:判断广义表是否相同过程是,若 g1 和 g2 均为 NULL,则返回 true;若 g1 和 g2 中一个为 NULL,另一不为 NULL,则返回 false;若 g1 和 g2 均不为 NULL,若同为原子 且原子值不相等,则返回 false,若同为原子且原子值相等,则返回 Same(g1->link,g2->link), 若同为子表,则返回 Same(g1->val.sublist,g2->val.sublist) & Same(g1->link,g2->link)的 结果,若一个为原子另一个为子表,则返回 false。对应的算法如下:

数据结构数组与广义表知识点总结

数据结构数组与广义表知识点总结

数据结构数组与广义表知识点总结数组是一种线性数据结构,可以存储多个相同类型的元素。

它的特点是元素的大小固定,并且在内存中是连续存储的。

数组的访问方式是通过下标来访问,下标从0开始。

数组可以在编程中应用于各种情况,比如存储一组数字、一组字符串等。

广义表是一种扩展的线性数据结构,可以存储不同类型的元素。

它由元素和表构成,其中表可以是空表、原子或子表。

广义表可以递归定义,即子表可以包含更多的子表。

广义表的访问方式是通过递归来访问,可以对表的元素进行遍历和操作。

在数据结构中,数组和广义表都有自己的特点和用途,下面对它们的知识点进行总结:1.数组的特点及应用:-数组是一种线性数据结构,可以存储多个相同类型的元素。

-数组的内存分配是连续的,可以通过下标来访问元素。

-数组的大小固定,一旦定义后不能改变。

-数组的访问速度快,可以通过下标直接访问元素。

-数组适合用于存储一组相同类型的数据,比如一组数字、一组字符串等。

-数组的应用场景包括但不限于:排序算法、查找算法、图像处理、矩阵运算等。

2.数组的操作和常用算法:-初始化:可以直接赋值或使用循环初始化数组。

-访问元素:通过下标访问元素,下标从0开始。

-修改元素:直接通过下标修改元素的值。

-插入元素:需要移动插入位置之后的元素。

-删除元素:需要移动删除位置之后的元素。

-查找元素:可以使用线性查找或二分查找等算法。

-排序算法:比如冒泡排序、选择排序、插入排序等。

-数组还有一些常用的属性和方法,比如长度、最大值、最小值等。

3.广义表的特点及应用:-广义表是一种扩展的线性数据结构,可以存储不同类型的元素。

-广义表由元素和表构成,表可以是空表、原子或子表。

-广义表可以递归定义,即子表可以包含更多的子表。

-广义表的访问方式是通过递归遍历和操作。

-广义表适合存储一组不同类型的数据,比如存储学生信息、函数调用栈等。

-广义表的应用场景包括但不限于:函数式编程、树的表示、图的表示等。

四、串、数组和广义表

四、串、数组和广义表

四、串、数组和⼴义表(内容待完善)知识点串的模式匹配⼜称⼦串定位运算或串匹配。

在匹配中,将主串称为⽬标(串),⼦串称为模式(串)。

BF法(Brute Force):KMP法:串的模式匹配的两种⽅法。

BF法,朴素的串匹配法。

KMP法,尽可能的滑动得更远,利⽤部分的匹配结果。

朴素的模式匹配算法(BF算法)图⽰说明第⼀轮⽐较:第⼆轮⽐较:...... 原理⼀致,省略中间步骤第五轮:第六轮:第⼀轮:⼦串中的第⼀个字符与主串中的第⼀个字符进⾏⽐较若相等,则继续⽐较主串与⼦串的第⼆个字符若不相等,进⾏第⼆轮⽐较第⼆轮:⼦串中的第⼀个字符与主串中第⼆个字符进⾏⽐较......第N轮:依次⽐较下去,直到全部匹配代码实现:(略)BF算法优点:思想简单,直接,缺点:每次字符不匹配时,都要回溯到开始位置,时间开销⼤。

时间复杂度 O((n-m+1)*m) 。

KMP模式匹配算法图⽰说明:从图中,我们可以很容易的发现,因为前⾯的字符,S和T中存在同的元素,所以S不必回溯到S[1]的位置,T也不必回溯到T[0]的位置。

我们就可直接跳过对相同元素的回溯⽐较,直接⽐较S[8]与T[3]。

因此我们构建⼀个next数组储存回溯位置。

KMP算法的思想:假设在模式匹配的进程中,执⾏T[i]和W[j]的匹配检查。

若T[i]=W[j],则继续检查T[i+1]和W[j+1]是否匹配。

next数组两种求法(1)第⼀种求法:根据前⼀个字符的next值求初始化:代码实现:1 char t[]={"ababaabab"};2 int Len=strlen(t);34 int i = 0, j = -1;5 int next[len];6 next[0]=-1;7 while (i < len - 1) {8 if ((j == -1) || t[i] == t[j]) {9 ++i, ++j;10 next[i] = j;11 }else{12 j = next[j];13 }14 }1516 for(i=0;i<len;i++)17 {printf("next[%d]->%d\n",i,next[i])}(2)第⼆种求法:根据最⼤公共元素长度求的求法))next数组优化(nextval的求法当⼦串中有多个连续重复的元素,例如主串 S=“aaabcde” ⼦串T=“aaaaax” 在主串指针不动,移动⼦串指针⽐较这些值,其实有很多⽆⽤功,因为⼦串中5个元素都是相同的a,所以我们可以省略掉这些重复的步骤。

串数组和广义表

串数组和广义表

if (j = 0 || S[i] = T[j]) { ++i; ++j; }
// 继续比较后继字符
else j = next[j];
// 模式串向右移动
}
if (j > T[0]) return i-T[0]; // 匹配成功
else return 0;
} // Index_KMP
第21页,此课件共59页哦
(13) DestroyString(&S)
//串销毁
}ADT String
第7页,此课件共59页哦
北京林业大学信息学院
22002222年年22月月2200日日
串的存储结构
顺序存储
链式存储
第8页,此课件共59页哦
22002222年年22月月2200日日
顺序存储表示
typedef struct{
char *ch;
s'a1a2an'
串名
串值 串长
第4页,此课件共59页哦
n
空串
n=0
22002222年年22月20日
a=‘BEI’, b=‘JING’ c=‘BEIJING’
d=‘BEI JING’
第5页,此课件共59页哦
子串 主串
字符位置 子串位置 串相等
空格串
22002222年年22月月2200日日
串的抽象数据类型
} else j = nextval[j];
} } // get_nextval
第25页,此课件共59页哦
模式串t=‘abcaabbca’,该模式串的next数组的值是
( D),nextval数组的值是( )F
A. 0 1 1 1 2 2 1 1 1 B. 0 1 1 1 2 1 2 1 1
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第5周 串和数组

设计1:存储格式转换问题

行 1 1 3 3
列 2 3 1 3
值 2 1 4 3
列 1 2 3 3
行 3 1 1 3
值 4 2 1 3
设计1:存储格式转换问题

2. 基本要求 (1)设计三元祖表的输出形式 (2)输出:稀疏矩阵的两种存储结果 (3)尝试分析其算法的时间复杂度
设计1:存储格式转换问题

实现提出


可以采用类似稀疏矩阵快速转置算法中的处理。即 先由行优先存储矩阵计算出各列第一个非零元素的 存储位置;然后扫描行优先存储矩阵,把各个元素 直接存放到该在的位置。 关键是计算如下表格
Col Num [col] Cpot [col] 1 1 1 2 1 2 3 2 3

cpot[col]=cpot[col-1]+num[col-1]
设计1:存储格式转换问题

思考:如何把列优先存储转换为行优先存储
相关文档
最新文档