34数据结构作业_第1页
34数据结构作业_第2页
34数据结构作业_第3页
34数据结构作业_第4页
34数据结构作业_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第三章3.5 假设以S和X分别表示入栈和出栈的操作,则初态和终态均为空栈的入栈和出栈的操作序列可以表示为仅由S和X组成的序列。称可以操作的序列为合法序列(例如,SXSX为合法序列,SXXS为非法序列)。试给出区分给定序列为合法序列或非法序列的一般准则,并证明:两个不同的合法(栈操作)序列(对同一输入序列)不可能得到相同的输出元素(注意:在此指的是元素实体,而不是值)序列。解:一般准则:任何前n个序列中S的个数一定大于或等于X的个数且整个序列中S的个数一定等于X的个数。证明:设两个合法序列为:T1=SXST2=SXX 假定前n个操作都相同,从第n+1个操作开始,为序列不同的起始操作点。由于前n个

2、操作相同,故此时两个栈(不妨为栈A、B)的存储情况完全相同,假设此时栈顶元素均为a。第n+1个操作不同,不妨T1的第n+1个操作为S,T2的第n+1个操作为X。T1为入栈操作,假设将b压栈,则T1的输出顺序一定是先b后a;而T2将a退栈,则其输出顺序一定是先a后b。由于T1的输出为ba,而T2的输出顺序为ab,说明两个不同的合法栈操作序列的输出元素的序列一定不同。3.9 试将下列递推过程改写为递归过程。void ditui(int n)int i;i = n;while(i>1)cout<<i-;解:Void digui(int n)if (n=2) printf(“%d”,

3、n);else printf(“%d”,n); digui(n-1); 3.10 试将下列递归过程改写为非递归过程。void test(int &sum)int x;cin>>x;if(x=0) sum=0;elsetest(sum);sum+=x;cout<<sum;解:void test(int & sum)sqstack s;int x;scanf("%d",&x);initstack(s);while(x!=0)*s.front+=x;scanf("%d",&x);sum=0;int e;p

4、rintf("%d",sum);while(s.front!=s.base)e=*(-s.front);sum+=e;printf("%d",sum);3.15 假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两个栈,它们的栈底分别设在数组的两个端点。试编写实现这个双向栈tws的三个操作:初始化inistack(tws)、入栈push(tws,i,x)和出栈pop(tws,i)的算法,其中i为0或1,用以分别指示设在数组两端的两个栈,并讨论按过程(正/误状态变量可设为变参)或函数设计这些操作算法各有什么有缺点。解:程序源代码:#inclu

5、de<stdio.h>#include<malloc.h>#define STACK_INIT_SIZE 100#define TURE 1#define FALSE 0#define ok 1#define error 0#define INFEASIBLE -1typedef int selemtype ;typedef int status;typedef structint * base2;selemtype * top2; int stacksize;sqstack;status INITstack(sqstack * s)int * p;p=(selemty

6、pe *) malloc (STACK_INIT_SIZE * sizeof(selemtype);(*s).base0=(*s).top0=p;(*s).base1=(*s).top1=p+STACK_INIT_SIZE-1;if(!(*s).base0) exit(-2);if(!(*s).base1) exit(-2);return ok;status Push(sqstack * s,int i,selemtype e)if(i=0)if (*s).top0>=(*s).base0+(STACK_INIT_SIZE/2)-1) return error;else *(*s).to

7、p0+=e;return ok;if(i=1)if(*s).top1<=(*s).base1-(STACK_INIT_SIZE/2)+1) return error;else *(*s).top1-=e;return ok; return error;status Pop(sqstack * s,int i,selemtype * e)if(i=0&&(*s).top0=(*s).base0) return error;if(i=1&&(*s).top1=(*s).base1) return error;if(i=0) *e=*(-(*s).top0);r

8、eturn ok;if(i=1) *e=*(-(*s).top1);return ok;void main()sqstack sta;selemtype e;selemtype * p;int i;if(INITstack(& sta) printf("双栈已被创建n");printf("请输入进栈端(0/1)及进栈元素:n");scanf("%d %d",&i,&e);if(Push(&sta,i,e) printf("元素已入栈n");printf("请输入进栈端(0/

9、1)及进栈元素:n");scanf("%d %d",&i,&e);if(Push(&sta,i,e) printf("元素已入栈n");printf("请输入进栈端(0/1)及进栈元素:n");scanf("%d %d",&i,&e);if(Push(&sta,i,e) printf("元素已入栈n");printf("左端栈元素:");p=sta.base0;while(sta.top0!=p)printf(&quo

10、t;%d ",*p);p+;printf("右端栈元素:");p=sta.base1;while(sta.top1!=p)printf("%d ",*p);p-;printf("n请输入出栈端(0/1):n");scanf("%d",&i);if(Pop(&sta,i,&e) printf("n栈顶元素 %d 出栈n",e); printf("左端栈元素:");p=sta.base0;while(sta.top0!=p)printf(&quo

11、t;%d ",*p);p+;printf("右端栈元素:");p=sta.base1;while(sta.top1!=p)printf("%d ",*p);p-;运行结果:3.21 假设表达式有单字母变量和双目四则运算符构成。试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰表达式。解:程序源代码:#include<stdio.h>#include<malloc.h>#define SIZE 100typedef char selemtype ;typedef structselemtype * base;s

12、elemtype * top;int size; stack;int Prior(char c1,char c2)char ch5="#+-*/"int i=0,j=0;if(c1='(') return 0;while(chi && chi!=c1) i+;if(i=2) i-;/ 加和减可认为是同级别的运算符if(i=4) i-;/ 乘和除可认为是同级别的运算符while(chj && chj!=c2) j+;if(j=2) j-;if(j=4) j-;if(i>j) return 1;else return 0;v

13、oid main()stack sta;char ch=0,ct;sta.base=(selemtype *)malloc(SIZE*sizeof(selemtype);if(!sta.base ) exit(0);sta.top=sta.base;sta.size=0;*sta.top+='#'printf("please enter the expression:n");while(ch!='#'&&*sta.base='#')ch=getchar();if('a'<=ch&&

14、amp;ch<='z') printf(" %c ",ch);else if(ch='#')ct=*(-sta.top);while(ct!='#')printf(" %c ",ct);ct=*(-sta.top);-sta.top;elseif(ch='(') *sta.top+=ch; else if(ch=')') ct=*(-sta.top);while(ct!='(')printf(" %c ",ct);ct=*(-sta.

15、top); else ct=*(sta.top-1);if(Prior(ct,ch)=0)*sta.top+=ch;elsect=*(-sta.top); while(Prior(ct,ch)printf(" %c ",ct); ct=*(-sta.top);*(+sta.top)=ch;+sta.top; 运行结果:3.22 如题3.21的假设条件,试写一个算法,对以逆波兰式表示的表达式求值。解:程序源代码:#include<iostream.h>#include<malloc.h>#define max_size_stack 100#define

16、 incre 10#define ok 1#define error -100typedef int elemtype2;typedef int status;typedef structelemtype2 * top;elemtype2 * base;int size;stack2;status initstack2(stack2 & da)da.base=(elemtype2*)malloc(max_size_stack*sizeof(elemtype2);if(!da.base) cout<<"操作失败,程序执行无效!"<<endl;d

17、a.top=da.base;da.size=max_size_stack;return ok;status pop2(stack2 & da, elemtype2 & e)if(da.base=da.top) return error;e=*(-da.top);return ok;status push2(stack2 & da,elemtype2 e)if(da.top-da.base>=da.size) da.base=(elemtype2 *)realloc(da.base,(da.size+incre)*sizeof(elemtype2);if(!da.b

18、ase) cout<<"操作失败,程序执行无效!"<<endl;da.top=da.base+da.size;da.size+=incre;*da.top+=e;return ok;int coun(elemtype2 e1,elemtype2 e2,char cch)switch(cch)case '+': return e1+e2;case '-': return e1-e2;case '*': return e1*e2;case '/': if(e2=0) return error

19、;else return e1/e2; case '#': return ok;break;default: return error;void main()char cch;int i,count=0,e1,e2;stack2 da;initstack2(da);cout<<"请输入表达式的逆波兰式:(#表结束)"<<endl;for(cch='1',i=0;cch!='#'&&i<20;i+)cin>>cch;if(cch!='+'&&

20、;cch!='-'&&cch!='*'&&cch!='/'&&cch!='#')push2(da,cch-48);else if(cch!='#')pop2(da,e2);pop2(da,e1);if(coun(e1,e2,cch)=-100) cout<<"表达是不合法:"<<endl; cout<<"操作失败,程序执行无效!"<<endl;elsepush2(da,coun(e

21、1,e2,cch); else pop2(da,e1); cout<<"表达式的值为:"<<e1<<endl;运行结果:3.14 若以1234作为双端队列的输入序列,试分别求出满足以下条件的输出序列: (1) 能由输入受限的双端队列得到,但不能由输出受限的双端队列得到的输出序列。 (2) 能由输出受限的双端队列得到,但不能由输入受限的双端队列得到的输出序列。(3) 既不能由输入受限的双端队列得到,也不能由输出受限的双端队列得到的输出序列。解:1,2,3,4输入受限12344和2不可相连1,2,3,4输出受限121和2不可分开4在1,3或2

22、,3之间由上分析可知:输出受限不可得到:1243,3412,1342,1432,3142,4132,1324,1423,2143,3421,2341,2431,3241,4231,2314,2413输入受限不可得到:1243,3241,1423,34213.29 如果希望循环队列中的元素都能得到利用,则需设置一个标志域tag,并以tag的值为0和1来区分,尾指针和头指针值相同时的队列状态是“空”还是“满”。试编写与此结构相应的入队列和出队列的算法,并从时间和空间角度讨论设标志和不设标志这两种方法的使用范围(如当循环队列容量较小而队列中每个元素占的空间较多时,哪一种方法较好)。解:程序源代码:#

23、include<iostream.h>#include<stdlib.h> #define maxqsize 5#define ok 1#define error 0typedef int qelemtype;typedef int status;typedef structqelemtype * base;int front;int rear;int tag;squeue;status initqueue(squeue & sq)sq.base=(qelemtype*)malloc(maxqsize*sizeof(qelemtype);if(!sq.base)

24、 exit(-2);sq.front=sq.rear=0;sq.tag=0;return ok;status enqueue(squeue & sq,qelemtype e)if(sq.rear=sq.front&&sq.tag) return error;sq.basesq.rear=e;sq.rear=(sq.rear+1)%maxqsize;if(sq.rear=sq.front) sq.tag=1;return ok;status dequeue(squeue & sq,qelemtype & e)if(sq.rear=sq.front&

25、&!sq.tag) return error;e=sq.basesq.front;sq.front=(sq.front+1)%maxqsize;if(sq.tag=1) sq.tag=0;return ok;void main()squeue sq;qelemtype e;int i;initqueue(sq);cout<<"请输入队列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;cout<<"请输入队

26、列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;cout<<"请输入队列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;if(dequeue(sq,e) cout<<"队头元素:"<<e<<"已删除"<<en

27、dl;cout<<"队列中元素为:"<<endl;for(;dequeue(sq,e);)cout<<e<<" "cout<<endl;运行结果:3.30 假设将循环队列定义为:以域变量rear和length分别指示循环队列中队尾元素的位置和内含元素的个数。试给出此循环队列的队满条件,并写出相应的入队列和出队列的算法(在出队列的算法中要返回队头元素)。解:程序源代码:#include<iostream.h>#include<stdlib.h>#define max 3#d

28、efine ok 1#define error 0typedef int status;typedef int selemtype;typedef structselemtype * base;int rear;int length;squeue;status initqueue(squeue & sq)sq.base=(selemtype *)malloc(max*sizeof(selemtype);if(!sq.base) exit(-2);sq.rear=0;sq.length=0;return ok;status enqueue(squeue & sq,selemtyp

29、e e)if(sq.length>=max) return error;sq.basesq.rear=e;sq.rear=(sq.rear+1)%max;sq.length+;return ok;status dequeue(squeue & sq,selemtype & e)if(sq.length<=0) return error;e=sq.base(sq.rear+max-sq.length)%max;sq.length-;return ok;void main()squeue sq;selemtype e;initqueue(sq);cout<<

30、"请输入队列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已满元素未被插入"<<endl;cout<<"请输入队列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已

31、满元素未被插入"<<endl;cout<<"请输入队列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已满元素未被插入"<<endl;cout<<"请输入队列元素:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"&

32、lt;<endl;else cout<<"队列已满元素未被插入"<<endl;if(dequeue(sq,e) cout<<"队头元素:"<<e<<"已删除"<<endl;cout<<"队列中元素为:"<<endl;for(;dequeue(sq,e);)cout<<e<<" "cout<<endl;运行结果:3.31 假设称正读和反读都相同的字符序列为“回文

33、”,例如,abba和abcba是回文,abcde和ababab则不是回文。试写一个算法判别读入的一个以为结束符的字符序列是否是“回文”。解:程序源代码:#include<iostream.h>#include<stdlib.h>#define max 10typedef char elemtype;typedef structelemtype * base;int front;int rear;squeue;void main()squeue sq;char e1=0,e2=0,ch;int i,n;sq.base=(elemtype *)malloc(max*size

34、of(elemtype);sq.front=sq.rear=0;cout<<"请输入字符序列:"<<endl;while(ch!=''&&(sq.rear+1)%max!=sq.front)cin>>ch;sq.basesq.rear=ch;sq.rear=(sq.rear+1)%max;if(sq.basesq.rear-1='') sq.rear-;if(sq.rear+1)%max=sq.front)cout<<"队列已满"<<endl;n=

35、(sq.rear-sq.front+1);for(i=1;i<=n/2&&e1=e2;i+)e1=sq.basesq.front+i-1;e2=sq.basesq.rear-i;if(i>=n/2&&e1=e2) cout<<"该字符序列为回文"<<endl;else cout<<"该字符序列不为回文"<<endl;运行结果:3.34 假设在如教科书节中图3.9所示的铁道转轨网的输入端有n节车厢:硬座、硬卧和软卧(分别以P,H和S表示)等待调度,要求这三种车厢在输

36、出端铁道上的排列次序为:硬座在前,软卧在中,硬卧在后。试利用输出受限的双端队列对这n节车厢进行调度,编写算法输出调度的操作序列:分别以字符E和D表示对双端队列的头端进行入队列和出队列的操作;以字符A表示对双端队列的尾端进行入队列的操作。解:程序源代码:#include<iostream.h>#include<stdlib.h>#define max 10#define ok 1#define error 0typedef int status;typedef int elemtype;typedef structelemtype * base;int front ;in

37、t rear ;int tag;xqueue;status initqueue(xqueue & sq)sq.base=(elemtype *)malloc(max *sizeof(elemtype);if(!sq.base) exit(-2);sq.front=sq.rear=0;sq.tag=0;return ok;status enqueue(xqueue & sq,elemtype e)elemtype a;if(sq.front=sq.rear&&sq.tag) return error;if(sq.front=sq.rear&&!sq

38、.tag) sq.basesq.rear=e;sq.rear=(sq.rear+1)%max;if(sq.front=sq.rear) sq.tag=1;elsea=(sq.basesq.front+sq.base(sq.rear+max-1)%max)/2;if(e>=a)sq.basesq.rear=e;sq.rear=(sq.rear+1)%max;if(sq.front=sq.rear) sq.tag=1;elsesq.base(sq.front+max-1)%max=e;sq.front=(sq.front+max-1)%max;if(sq.front=sq.rear) sq.

39、tag=1;return ok;status dequeue(xqueue & sq,elemtype & e)if(sq.front=sq.rear&&!sq.tag) return error;elsee=sq.basesq.front;sq.front=(sq.front+1+max)%max;sq.tag=0;return ok;void main() xqueue sq;elemtype e;initqueue(sq);cout<<"请输入作业预计时间:"<<endl;cin>>e;if(enqu

40、eue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已满元素未被插入"<<endl;cout<<"请输入作业预计时间:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已满元素未被插入"<<endl;cout<<"请输入作业预计

41、时间:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已满元素未被插入"<<endl;cout<<"请输入作业预计时间:"<<endl;cin>>e;if(enqueue(sq,e) cout<<"元素已插入"<<endl;else cout<<"队列已满元素未被插入&q

42、uot;<<endl;if(dequeue(sq,e) cout<<"队头元素:"<<e<<"已删除"<<endl;cout<<"队列中元素为:"<<endl;for(;dequeue(sq,e);)cout<<e<<" "cout<<endl;运行结果:3.34 假设在如教科书节中图3.9所示的铁道转轨网的输入端有n节车厢:硬座、硬卧和软卧(分别以P,H和S表示)等待调度,要求这三种车厢在输出端

43、铁道上的排列次序为:硬座在前,软卧在中,硬卧在后。试利用输出受限的双端队列对这n节车厢进行调度,编写算法输出调度的操作序列:分别以字符E和D表示对双端队列的头端进行入队列和出队列的操作;以字符A表示对双端队列的尾端进行入队列的操作。解:程序源代码:#include<iostream.h>#include<stdlib.h>#define max 10#define ok 1#define error 0typedef int status;typedef char elemtype;typedef structelemtype * base;int front ;int

44、 rear ;int tag;xqueue;status initqueue(xqueue & sq)sq.base=(elemtype *)malloc(max *sizeof(elemtype);if(!sq.base) exit(-2);sq.front=sq.rear=0;sq.tag=0;return ok;status enqueuerear(xqueue & sq,elemtype e)if(sq.front=sq.rear&&sq.tag) return error;sq.basesq.rear=e;sq.rear=(sq.rear+1)%max

45、;if(sq.front=sq.rear) sq.tag=1;return ok;status enqueuetop(xqueue & sq,elemtype e)if(sq.front=sq.rear&&sq.tag) return error;sq.base(sq.front-1+max)%max=e;sq.front=(sq.front-1+max)%max;if(sq.front=sq.rear) sq.tag=1;return ok;status dequeue(xqueue & sq,elemtype & e)if(sq.front=sq.r

46、ear&&!sq.tag) return error;elsee=sq.basesq.front;sq.front=(sq.front+1+max)%max;sq.tag=0;return ok;status empty(xqueue sq)if(sq.front=sq.rear&&!sq.tag) return ok;else return error;status gettop(xqueue sq,elemtype & e)if(empty(sq) return error;e=sq.basesq.front;return ok;void main(

47、) xqueue sq;elemtype e;char ch25,cch;int i,n;initqueue(sq);cout<<"请输入车厢节数:"<<endl;cin>>n;cout<<"请输入车厢次序:"<<endl;for(i=1;i<=n;i+)cin>>cch;chi-1=cch; for(i=1;i<=n;i+)if(empty(sq) enqueuetop(sq,chi-1);cout<<" E "else if(chi-1

48、='H') enqueuerear(sq,chi-1);cout<<" A "if(chi-1='P') enqueuetop(sq,chi-1);cout<<" E "if(chi-1='S') gettop(sq,e);if(e='S')enqueuetop(sq,chi-1);cout<<" E "elsewhile(e='P')dequeue(sq,e);cout<<" D " g

49、ettop(sq,e);enqueuetop(sq,chi-1);cout<<" E "if(!empty(sq) for(;dequeue(sq,e);)cout<<" D "cout<<endl;运行结果:第四章4.11编写算法,求得所有包含在串s中而不包含在串t中的字符(s中重复的字符只选一个)构成的新串r,以及r中每个字符在s中第一次出现的位置。解:程序源代码:#include<iostream.h>#include<stdlib.h>#include<malloc.h>#d

50、efine ok 1typedef int status;typedef structchar * ch;int * pos;int length;string;status strassign(string & r,char * chars)int i,j,k;char * c,* cc;if(r.ch) free(r.ch);i=0;c=chars;while(*c)if(*c!='*')i+;c+;c+;if(!i)r.ch=0;r.pos=0;elseif(!(r.ch=(char *)malloc(i*sizeof(char)exit(-2);if(!(r.p

51、os=(int *)malloc(i*sizeof(int)exit(-2);j=k=i=1;c=chars;cc=r.ch;while(cj-1)if(cj-1!='*')cci-1=cj-1;r.posk-1=j-1;i+;k+;r.length+;j+;return ok;void main()int i,j,m,n;string r=0,0,0;char s20,t20;cout<<"请输入串s:"<<endl;cin>>s;cout<<"请输入串t:"<<endl;cin>>t;for(n=0;sn;n+);for(m=0;tm;m+);for(i=1;i<=n;i+)if(si-1!='*')for(j=i+1;j<=n;j+)if(si-1=sj-1) sj-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论