数据结构实践-第6周 串数组和广义表(设计)
- 格式:ppt
- 大小:410.50 KB
- 文档页数:5
数据结构串、数组和广义表知识点总结
数据结构是计算机科学中研究数据如何组织、存储、管理和操作的学科。
三个常见的数据结构串、数组和广义表都是用于存储和操作数据的。
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。
第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。
数据结构数组与广义表知识点总结数组是一种线性数据结构,可以存储多个相同类型的元素。
它的特点是元素的大小固定,并且在内存中是连续存储的。
数组的访问方式是通过下标来访问,下标从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,所以我们可以省略掉这些重复的步骤。
数据结构05数组与广义表数组与广义表可以看做是线性表地扩展,即数组与广义表地数据元素本身也是一种数据结构。
5.1 数组地基本概念5.2 数组地存储结构5.3 矩阵地压缩存储5.4 广义表地基本概念数组是由相同类型地一组数据元素组成地一个有限序列。
其数据元素通常也称为数组元素。
数组地每个数据元素都有一个序号,称为下标。
可以通过数组下标访问数据元素。
数据元素受n(n≥1)个线性关系地约束,每个数据元素在n个线性关系地序号 i1,i2,…,in称为该数据元素地下标,并称该数组为n维数组。
如下图是一个m行,n列地二维数组A矩阵任何一个元素都有两个下标,一个为行号,另一个为列号。
如aij表示第i行j列地数据元素。
数组也是一种线性数据结构,它可以看成是线性表地一种扩充。
一维数组可以看作是一个线性表,二维数组可以看作数据元素是一维数组(或线性表)地线性表,其一行或一列就是一个一维数组地数据元素。
如上例地二维数组既可表示成一个行向量地线性表: A1=(a11,a12,···,a1n)A2=(a21,a22, ···,a2n)A=(A1,A2, ···,Am) ············Am=(am1,am2, ···,amn)也可表示成一个列向量地线性表:B1=(a11,a21,···,am1)B2=(a12,a22, ···,am2)A=(B1,B2, ···,Bm) ············Bn=(a1n,a2n, ···,amn)数组地每个数据元素都与一组唯一地下标值对应。
中南大学《数据结构与算法》数组与广义表学习报告学习报告数组与广义表学习报告A 数组1学习目标:进一步深刻的了解数组的定义与运算,对数组的顺序存储结构更深入的认知。
也是对曾经学过的知识的进一步巩固。
更重要的是学习特殊矩阵的压缩存储方法实现矩阵之间的加减运算,如三角矩阵,对称矩阵,以及稀疏矩阵的一些基本操作。
2学习过程:数组是一种数据类型。
从逻辑结构上看,数组可以看成是一般线性表的扩充。
二维数组可以看成是线性表的线性表,应此可以利用线性表来存储多维数组。
把多维数组尤其是二维数组转换为线性表尤为重要,二维数组可以作为一个矩阵看待我们还可以将数组A m×n看成另外一个线性表:B=(β1,,β2,,… ,βm),其中βi(1≤i ≤m)本身也是一个线性表,称为行向量,即:βI= (a i1,a i2,…,a ij ,…,a in)。
这样把二维数组转换为了一维数组就能很轻松的进行操作与运算了。
数组的抽象数据类型定义(ADT Array)数据对象:D={ a j1j2…jn| n>0,称为数组的维数,j i是数组的第i维下标,1≤j i≤b i,bi为数组第i维的长度,a j1j2…jn∈ElementSet}基本操作:包括initArray(), destoryArray(), getElement(), setElement()1先实现了一位动态数组的存储#include<iostream>using namespace std;void main(){int *a ,n=10;int i;a=(int *)calloc(n,sizeof(int));for(i=0;i<n;i++)a[i]=i+1;for (i=0;i<n;i++)cout<<a[i]<<"\t";free(a);}通过实现了这个程序学到了更进一步的知道了如何动态申请内存空和释放动态深情的数组内存空间的calloc()函数,其函数原型为(void*)calloc(unsigned n ,sizeof(int))。