1、数据结构的语言算法作者:林庆达班级:计算机(7)班学号:80号 以下数据结构算法由C语言编译,并在TC上运行通过,其中,扩展名为”.CPP”的为头文件,运行时只需将头文件与相应算法连接即可。第一章 绪论(预备知识)练习1.16/*试写一算法,自大至小输出顺序读入的三个整数X,Y和Z的值*/62#include void swap(int *x,int *y,int *z) int t; if(*x*y) t=*x;*x=*y;*y=t; if(*y*z) t=*y;*y=*z;*z=t; if(*x*y) t=*x;*x=*y;*y=t; main()int a,b,c;scanf(%d,%d
2、,%d,&a,&b,&c);swap(&a,&b,&c);printf(%d %d %d,a,b,c);第二章 线性表1顺序表实现顺序表基本算法的头文件sq.cpp为:#include#define MaxLen 50/*顺序表中最多元素个数*/typedef int elemtype;typedef elemtype sqlistMaxLen;int create(sqlist A)/*创建线形表*/ int i,n; printf(创建一个顺序表:n); printf(输入元素个数:); scanf(%d,&n); for(i=0;in;i+) printf(输入第%d个元素值:,i+1)
3、; scanf(%d,&Ai); return n;void disp(sqlist A,int n)/*输出一个顺序表*/ int i; printf(输出一个顺序表: n); if(n=0) printf(空表); for(i=0;in;i+) printf(%d ,Ai); printf(n);int ins(sqlist A,int n,int i,elemtype x)/*在顺序表第i个元素前插入一个元素x,若i=0,则新元素作为第一个元素,若i=1,则插入在最后*/ int j; if(in) printf(i值下溢或上溢n); else for(j=n-1;j=i;j-) Aj+
4、1=Aj; /*将第i个元素及其后的元素后移*/ Ai=x;n+;/*顺序表长度加1*/ return n;int del(sqlist A,int n,int i)/*在顺序表中删除第i个元素*/ int j; if(in) printf(i值下溢或上溢n); else for(j=i-1;jn;j+) Aj=Aj+1; /*将第i个元素之后的元素前移覆盖Ai*/ n-; /*顺序表长度减1*/ return n;int find(sqlist A,int n,elemtype x)/*在一个有n个元素的顺序表A中查找元素值为x的元素*/ int i=0; while(i=n&Ai!=x)
5、i+; if(i=An-1) An=x; /*若x大于最后的元素,则将其插入到最后*/ else i=0; while(xAi) i+;/*查找插入位置i*/ for(j=n;j=i;j-) Aj+1=Aj; /*移出插入x的位置*/ Ai=x; return (n+1);/*顺序表长度增1*/void main() sqlist A; int n; n=create(A); disp(A,n); n=insert(A,n,10);/*插入元素10*/ disp(A,n); getch();/*运行结果:创建一个顺序表 输入元素个数:3 输入第1个元素值:6输入第1个元素值:9输入第1个元素值
6、:14输出一个顺序表6 9 14输出一个顺序表6 9 10 14 */练习2.12/*设A=(a1,am)和B=(b1,bm)均为顺序表,A和B分别为A和B中除去最大共同前缀后的子表(例如,A=(x,y,y,z,x,z),B=(x,y,y,z,y,x,x,z),则两者中最大的共同前缀为(x,y,y,z),在两表中除去最大的共同前缀后的子表分别为A=(x,z)和B=(y,x,x,z)。若A=B=空表,则A=B;若A=空表,B!=空表,或者两者均不为空表,且A的首元小于B的首元,则AB。试写一个比较A,B大小的算法(请注意:在算法中,不要破坏原表A和B,并且,也不一定先求得A和B才能进行比较)*/
7、#includesq.cppint comp(sqlist A,int na,sqlist B,int nb) int i=0,j=0;while(ina&jnb&Ai+=Bj+);/*比较相同部分*/i-;j-;if(i=na&j=nb) return 0;/*a=b*/if(i=na&j!=nb) return -1;/*ab*/if(AiBj)return 1;else return -1;void main() sqlist A,B;int na,nb,n;na=create(A);nb=create(B);n=comp(A,na,B,nb);switch(n)case 0:print
8、f(A=Bn); break;case 1:printf(ABn); break;case -1:printf(AB*/练习2.16/*删除A中第i个元素起的k个元素*/#includesq.cppint delk(sqlist A,int *n,int i,int k)int j;if(i*n)printf(i,k参数不正确n);return 0;elsefor(j=i+k-1;j*n;j+)Aj-k=Aj;(*n)-=k;return 1;void main()sqlist A;int n,i,k;n=create(A);disp(A,n);printf(输入i,k:);scanf(%d
9、%d,&i,&k);if(delk(A,&n,i,k)=1)disp(A,n); getch(); /*运行结果:创建一个顺序表 输入元素个数:5输入第1个元素值:1输入第1个元素值:2输入第1个元素值:3输入第1个元素值:4输入第1个元素值:5输出一个顺序表1 2 3 4 5输入I,k:2 2输出一个顺序表1 4 5 */ 练习2.21/*试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,.,an)逆置为(an,an-1,.,a1).*/#includesq.cppvoid invert(sqlist A,int n) int m=n/2,i; /*m为长度的一半即
10、n2*/ elemtype temp; for(i=0;i=0&j=0)if(Ai-1Bj-1)i-;elseif(Ai-1Bj-1)j-;else/*Ai-1=Bj-1*/Ck+=Ai-1;i-;j-;return k-1;void main()sqlist A,B,C;int na,nb,nc;na=create(A);disp(A,na);nb=create(B);disp(B,nb);nc=intersect(A,na,B,nb,C);disp(C,nc);/*习题2.25*/*假设以两个元素依值递增有序排列的线性表A和B分别表示两个集合(即同一表中的元素值各不相同),现要求另开辟空间
11、构成一个线性表C,其元素为A和B中元素的交集,且表C中的元素也依值递增有序排列.试对顺序表编写求C的算法*/#includesq.cppint unions(sqlist A,int na,sqlist B,int nb,sqlist C)int i=0,j=0,k=0;while(ina&jnb)if(AiBj)Ck+=Bj+;else/*Ai=Bi*/Ck+=Ai;i+;j+;if(ina)/*A还有元素*/for(j=i;jna;j+)Ck+=Aj;else if(jnb)/*B还有元素*/for(i=j;inb;i+)Ck+=Bi;return k;void main()sqlist
12、A,B,C;int na,nb,nc;na=create(A);disp(A,na);nb=create(B);disp(B,nb);nc=unions(A,na,B,nb,C);disp(C,nc);2. 线性表实现线性表基本算法的头文件slink.cpp为:#include#includetypedef int elemtype;/*定义数据域的类型*/typedef struct linknode/*定义节点类型*/ elemtype data; struct linknode *next;nodetype;nodetype *create()/*建立单链表,由用户输入各节点data域之
13、值,以0表示输入结束*/ elemtype d; nodetype *h=NULL,*s,*t; int i=1; peintf(建立一个单链表n); while(1) printf( 输入第%d个节点data域值:,i); scanf(%d,&d); if(d=0) break;/*以0表示输入结束*/ if(i=1)/*建立第一个节点*/ h=(nodetype *)malloc(sizeof(nodetype); h-data=d;h-next=NULL;t=h; else/*建立其余节点*/ s=(nodetype *)malloc(sizeof(nodetype); s-data=d
14、;s-next=NULL;t-next=s; t=s;/*始终指向生成的单链表的最后一个节点*/ i+; return h;void disp(nodetype *h)/*输出由h指向的单链表的所有data域之值*/ nodetype *p=h; printf(输出一个单链表:n ); if(p=NULL) printf(空表); while (p!=NULL) printf(%d ,p-data); p=p-next; printf(n);int len(nodetype *h)/*返回单链表的长度*/ int i=0; nodetype *p=h; while(p!=NULL) p=p-n
15、ext; i+; return i;nodetype find(nodetype *h,int i)/*返回第i个节点的指针*/ nodetype *p=h; int j=1; if(ilen(h)|i=0) return NULL;/*i上溢或下溢*/ else while (p!=NULL&jnext; return p; nodetype *ins(nodetype *h,int i,elemtype x)/*单链表head中第i个节点(i=0)之后插入一个data域为x的节点*/ nodetype *p,*s; s=(nodetype *)malloc(sizeof(nodetype)
16、;/*创建节点s*/ s-data=x; s-next=NULL; if(i=0)/*i=0:s作为单链表的第一个节点*/ s-next=h; h=s; else p=find(h,i);/*查找第i个节点,并由p指向该节点*/ if(p!=NULL) s-next=p-next; p-next=s; else printf(输入的i值不正确n); return h;nodetype *del(nodetype *n,int i)/*删除第i个节点*/ nodetype *p=h,*s; int j=1; if(i=1)/*删除第一个节点*/ h=h-next; free(p); else p
17、=find(h,i-1);/*查找第i-1个节点,并由p指向该节点*/ if(p!=NULL&p-next!=NULL) s=p-next;/*s指向要删除的节点*/ p-next=s-next; free(s); else printf(输入的i值不正确n); return h;void dispose(nodetype *h)/*释放单链表的所有节点占有的空间*/ nodetype *pa=h,*pb; if(pa!=NULL) pb=pa-next; if(pb=NULL)/*只有一个节点的情况*/ free(pa); else while(pb!=NULL)/*有两个及两个以上的节点的
18、情况*/ free(pa); pa=pb; pb=pb-next; free(pa); 练习2.22/*试写一算法,对单链表实现就地逆置*/#includeslink.cpp#includenodetype *invert(nodetype *h)/*实现单链表逆置*/nodetype *p,*q,*r;if(len(h)next;while(q!=NULL)r=q-next;q-next=p;p=q;q=r;h-next=NULL;h=p;return h;void main()nodetype *head;head=create();disp(head);head=invert(head)
19、;disp(head);/*运行结果建立一个单链表 输入第1节点data域值:1输入第2节点data域值:2输入第1节点data域值:3输入第1节点data域值:4输入第1节点data域值:5输入第1节点data域值:0输出一个单链表1 2 3 4 5 输出一个单链表5 4 3 2 1 */练习2.23/*设线性表A=(a1,a2,am),B=(b1,b2,bn),试写一个按下列规则合并A,B为线性表C的算法,即使得C=(a1,b1,am,bm,bm+1,bm) 当mn时。线性表A,B和C均以单链表做存储结构,且C表利用A表和B表中的结点空间构成。注意:单链表的长度值m和n均未显示存储*/#i
20、ncludeslink.cppnodetype *combine(nodetype *ha,nodetype *hb)nodetype *hc=ha,*pa=ha,*pb=hb,*q,*r;if(len(pa)!=len(pb)printf(两个单链表长度不同n);return NULL;while(pa!=NULL)q=pa-next;r=pb-next;pa-next=pb;pb-next=q;pa=q;pb=r;return(hc);void main()nodetype *heada,*headb,*headc;heada=create();headb=create();headc=c
21、ombine(heada,headb);disp(headc);练习2.26#includeslink.cppnodetype *connect(nodetype *h1,nodetype *h2)nodetype *pa=h1,*pb=h2,*h3,*pc;h3=(nodetype *)malloc(sizeof(nodetype);/*创建哨兵*/pc=h3;/*pc总是指向生成的新单链表的最后一个节点*/while(pa!=NULL&pb!=NULL)if(pa-datadata)pc-next=pa;pc=pa;pa=pa-next;elseif(pa-datapb-data)pc-n
22、ext=pb;pc=pb;pb=pb-next;else/*pa-data=pb-data的情况*/pc-next=pa;pc=pa;pa=pa-next;pb=pb-next;if(pa!=NULL) pc-next=pa;/*h1单链表还有节点时*/if(pb!=NULL) pc-next=pb;/*h2单链表还有节点时*/pc=h3;/*删除哨兵*/h3=h3-next;free(pc);return h3;void main()nodetype *head1,*head2,*head3;head1=create();head2=create();disp(head1);disp(hea
23、d2);head3=connect(head1,head2);disp(head3);练习2.34#include#includetypedef struct dnodeint data;struct dnode *link;dlist;dlist *xor(dlist *p1,dlist *p2)/*在c/c+中异或运算符不能对地址进行异或运算,所以先将地址值转换为长整形,然后进行异或运算,再将结果强制转换成地址。这是本函数的功能*/int add1,add2,add3;add1=(long)p1;add2=(long)p2;add3=add1add2;return(dlist *)add3
24、;dlist *create(dlist *e)int i=1,x;dlist *head,*r,*s,*pre;printf(创建一个双链表(以0结束)n);while(1)printf( 输入第%d节点值: ,i);scanf(%d,&x);if(x=0)/*生成最后一个节点的link值后退出循环*/pre-link=xor(r,NULL);/*将s-link置为前后节点地址之异或*/*e=pre;break;s=(dlist *)malloc(sizeof(dlist);/*创建一个节点*/s-data=x;if(i=1)/*是第一个节点的情况*/pre=head=s;r=NULL;/*
25、r为当前节点的前一个节点*/elsepre-link=xor(r,s);/*将s-link置为前后节点地址之异或*/r=pre;pre=s;i+;return head;void order(dlist *h,dlist *e)dlist *pre=NULL,*pre1,*p=h;printf(遍历节点序列: );if(h=NULL)printf(空表n);elsewhile(p!=e)/*遍历最后一节点前的所有节点*/printf(%d ,p-data);pre1=p;p=xor(pre,p-link);/*为下一个节点的地址*/pre=pre1;printf(%d ,e-data);pri
26、ntf(n);void main()dlist *h,*e;int i;h=create(&e);printf(从左向右);order(h,e);printf(从右向左);order(e,h);/*运行结果:创建一个双链表(以0结束) 输入第1节点值:3输入第1节点值:5输入第1节点值:8输入第1节点值:2输入第1节点值:6输入第1节点值:0从左向右遍历节点序列: 3 5 8 2 6 从右向左遍历节点序列: 6 2 8 5 3 */第三章 栈和队列实现栈基本算法的头文件stack.cpp为:#include#define MaxLen 20/*顺序栈存放的最多元素个数为Maxlen-1*/ty
27、pedef char elemtype;typedef struct sqstackelemtype dataMaxLen;int top;stack;void init(stack *st)/*初始化栈st*/st-top=0;int push(stack *st,elemtype x)/*入栈*/if(st-top=MaxLen-1)printf(栈溢出n);return 0;elsest-top+;st-datast-top=x;return 1;int pop(stack *st,elemtype *x)/*退栈*/if(st-top=0)printf(栈下溢出n);return 0;
28、else*x=st-datast-top;st-top-;return 1;int empty(stack *st)/*判断栈空*/if(st-top=0)return 1;elsereturn 0;int gettop(stack *st,elemtype *x)/*获取栈顶元素*/if(st-top=0)printf(栈下溢出n);return 0;else*x=st-datast-top;return 1;void disp(stack *st)/*输出栈的所有元素*/int i;for(i=st-top;i0;i-)printf(%d ,st-datai);printf(n);/*练习
29、3.19*/*假设一个算术表达式中可以包含三种括号,圆括号(和)、方括号和和花括号和,且这三种括号可按任意的次序嵌套使用(如:.(.).).编写判别给定表达式中所含括号是否正确配对出现的算法(已知表达式已存入数据元素为字符的顺序表中*/*输入:a+b+(c+d)+e+f*/#includestack.cpp#includeint correct(char *str)stack st;char x;int i,ok=1;init(&st);for(i=0;stri!=0;i+)switch(stri)case(:push(&st,();break;case:push(&st,);break;ca
30、se:push(&st,);break;case):if(!(pop(&st,&x)&x=()ok=0;break;case:if(!(pop(&st,&x)&x=)ok=0;break;case:if(!(pop(&st,&x)&x=)ok=0;break;if(!ok) break;if(empty(&st)&ok)return 1;elsereturn 0;void main()char *str;str=(char*)malloc(100*sizeof(char);printf(str: );scanf(%s,str);if(correct(str)printf(表达式括号匹配n);e
31、lseprintf(表达式括号不匹配n); getch();练习3.21#include#define MaxLen 100int trans(char str,char exp)int stMaxLen;/*作为栈使用*/char ch;int i=0,t=0,top=-1;/*t作为exp的下标,top作为st的下标,i作为str的下标*/while(ch=stri+)!=0)if(ch=0 & ch=0 & ch=0 & sttop!=()expt=sttop;top-;t+;top+;sttop=ch;else if(ch=*|ch=/)while (sttop=* | sttop=/)expt=sttop;top-;t+;top+;sttop=ch;while(top=0)expt=sttop;t+;top-;expt=0;return 1;int compvalue(char exp,int *n)int stMaxLen,d;/*作为栈使用*/char ch;int t=0,top=-1;/*t作为exp