34大数据结构作业.docx

上传人:b****8 文档编号:9242852 上传时间:2023-05-17 格式:DOCX 页数:36 大小:26.20KB
下载 相关 举报
34大数据结构作业.docx_第1页
第1页 / 共36页
34大数据结构作业.docx_第2页
第2页 / 共36页
34大数据结构作业.docx_第3页
第3页 / 共36页
34大数据结构作业.docx_第4页
第4页 / 共36页
34大数据结构作业.docx_第5页
第5页 / 共36页
34大数据结构作业.docx_第6页
第6页 / 共36页
34大数据结构作业.docx_第7页
第7页 / 共36页
34大数据结构作业.docx_第8页
第8页 / 共36页
34大数据结构作业.docx_第9页
第9页 / 共36页
34大数据结构作业.docx_第10页
第10页 / 共36页
34大数据结构作业.docx_第11页
第11页 / 共36页
34大数据结构作业.docx_第12页
第12页 / 共36页
34大数据结构作业.docx_第13页
第13页 / 共36页
34大数据结构作业.docx_第14页
第14页 / 共36页
34大数据结构作业.docx_第15页
第15页 / 共36页
34大数据结构作业.docx_第16页
第16页 / 共36页
34大数据结构作业.docx_第17页
第17页 / 共36页
34大数据结构作业.docx_第18页
第18页 / 共36页
34大数据结构作业.docx_第19页
第19页 / 共36页
34大数据结构作业.docx_第20页
第20页 / 共36页
亲,该文档总共36页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

34大数据结构作业.docx

《34大数据结构作业.docx》由会员分享,可在线阅读,更多相关《34大数据结构作业.docx(36页珍藏版)》请在冰点文库上搜索。

34大数据结构作业.docx

34大数据结构作业

实用标准文案

第三章

3.5假设以S和X分别表示入栈和出栈的操作,则初态和终态均为空栈的入栈和出栈的操作序列可以表示为仅由S和X组成的序列。

称可以操作的序列为合法序列(例如,SXSX为合法序列,SXXS为非法序列)。

试给出区分给定序列为合法序列或非法序列的一般准则,并证明:

两个不同的合法(栈操作)序列(对同一输入序列)不可能得到相同的输出元素(注意:

在此指的是元素实体,而不是值)序列。

解:

一般准则:

任何前n个序列中S的个数一定大于或等于X的个数且整个序列中S的个数一定等于X的个数。

证明:

设两个合法序列为:

T1=S⋯⋯X⋯⋯S⋯⋯

T2=S⋯⋯X⋯⋯X⋯⋯

假定前n个操作都相同,从第n+1个操作开始,为序列不同的起始操作点。

由于前n个操作相同,故此时两个栈(不妨为栈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试将下列递推过程改写为递归过程。

voidditui(intn)

{

精彩文档

实用标准文案

inti;

i=n;

while(i>1)

cout<

}

解:

Voiddigui(intn){

if(n==2)printf(“%d”,n);

else{

printf(“%d”,n);digui(n-1);}

}

3.10试将下列递归过程改写为非递归过程。

voidtest(int&sum)

{

intx;

cin>>x;

if(x==0)sum=0;

else

{

test(sum);

sum+=x;

}

精彩文档

实用标准文案

cout<

}

解:

voidtest(int&sum){

sqstacks;

intx;

scanf("%d",&x);

initstack(s);

while(x!

=0){

*s.front++=x;

scanf("%d",&x);

}

sum=0;

inte;

printf("%d",sum);

while(s.front!

=s.base){

e=*(--s.front);

sum+=e;

printf("%d",sum);

}

}

3.15假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两个栈,它

精彩文档

实用标准文案

的三个操作:

初始化

为0或1,用以分别指

)或函数设计这些操作

们的栈底分别设在数组的两个端点。

试编写实现这个双向栈tws

inistack(tws)、入栈push(tws,i,x)和出栈pop(tws,i)的算法,其中i示设在数组两端的两个栈,并讨论按过程(正/误状态变量可设为变参

算法各有什么有缺点。

解:

程序源代码:

#include

#include

#defineSTACK_INIT_SIZE100

#defineTURE1

#defineFALSE0

#defineok1

#defineerror0

#defineINFEASIBLE-1typedefintselemtype;

typedefintstatus;typedefstruct{

int*base[2];selemtype*top[2];

intstacksize;

}sqstack;

statusINITstack(sqstack*s){

精彩文档

实用标准文案

int*p;

p=(selemtype*)malloc(STACK_INIT_SIZE*sizeof(selemtype));

(*s).base[0]=(*s).top[0]=p;

(*s).base[1]=(*s).top[1]=p+STACK_INIT_SIZE-1;

if(!

(*s).base[0])exit(-2);

if(!

(*s).base[1])exit(-2);

returnok;

}

statusPush(sqstack*s,inti,selemtypee){

if(i==0){

if((*s).top[0]>=((*s).base[0]+(STACK_INIT_SIZE/2)-1))returnerror;

else*(*s).top[0]++=e;

returnok;

}

if(i==1){

if((*s).top[1]<=((*s).base[1]-(STACK_INIT_SIZE/2)+1))returnerror;

else*(*s).top[1]--=e;

returnok;

}

returnerror;

}

statusPop(sqstack*s,inti,selemtype*e){

精彩文档

实用标准文案

if(i==0&&(*s).top[0]==(*s).base[0])returnerror;

if(i==1&&(*s).top[1]==(*s).base[1])returnerror;if(i==0){

*e=*(--(*s).top[0]);

returnok;

}

if(i==1){

*e=*(--(*s).top[1]);

returnok;

}

}

voidmain()

{

sqstacksta;

selemtypee;

selemtype*p;

inti;

if(INITstack(&sta))printf("双栈已被创建\n");

printf("请输入进栈端(0/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("请输入进栈端(0/1)及进栈元素:

\n");

scanf("%d%d",&i,&e);

if(Push(&sta,i,e))printf("元素已入栈\n");

printf("左端栈元素:

");

p=sta.base[0];

while(sta.top[0]!

=p){

printf("%d",*p);

p++;

}

printf("右端栈元素:

");

p=sta.base[1];

while(sta.top[1]!

=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.base[0];

while(sta.top[0]!

=p){

精彩文档

实用标准文案

printf("%d",*p);

p++;}

printf("右端栈元素:

");

p=sta.base[1];

while(sta.top[1]!

=p){

printf("%d",*p);

p--;

}

}

运行结果:

3.21假设表达式有单字母变量和双目四则运算符构成。

试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰表达式。

解:

程序源代码:

#include

精彩文档

实用标准文案

#include

#defineSIZE100

typedefcharselemtype;

typedefstruct{

selemtype*base;

selemtype*top;

intsize;

}stack;

intPrior(charc1,charc2)

{

charch[5]="#+-*/";

inti=0,j=0;

if(c1=='(')return0;

while(ch[i]&&ch[i]!

=c1)i++;

if(i==2)i--;//加和减可认为是同级别的运算符

if(i==4)i--;//乘和除可认为是同级别的运算符

while(ch[j]&&ch[j]!

=c2)j++;

if(j==2)j--;

if(j==4)j--;

if(i>j)return1;

elsereturn0;

}

精彩文档

实用标准文案

voidmain(){

stacksta;

charch=0,ct;

sta.base=(selemtype*)malloc(SIZE*sizeof(selemtype));

if(!

sta.base)exit(0);

sta.top=sta.base;

sta.size=0;

*sta.top++='#';

printf("pleaseentertheexpression:

\n");

while(ch!

='#'&&*sta.base=='#'){

ch=getchar();

if('a'<=ch&&ch<='z')printf("%c",ch);

else

if(ch=='#'){

ct=*(--sta.top);

while(ct!

='#')

{printf("%c",ct);

ct=*(--sta.top);}

--sta.top;

}

else

if(ch=='(')*sta.top++=ch;

精彩文档

实用标准文案

else

if(ch==')'){

ct=*(--sta.top);

while(ct!

='(')

{printf("%c",ct);

ct=*(--sta.top);

}

}

else{

ct=*(sta.top-1);

if(Prior(ct,ch)==0)*sta.top++=ch;

else{

ct=*(--sta.top);

while(Prior(ct,ch))

{printf("%c",ct);

ct=*(--sta.top);}

*(++sta.top)=ch;

++sta.top;

}

}}}

运行结果:

精彩文档

 

实用标准文案

3.22如题3.21的假设条件,试写一个算法,对以逆波兰式表示的表达式求值。

解:

程序源代码:

#include

#include

#definemax_size_stack100

#defineincre10

#defineok1

#defineerror-100

typedefintelemtype2;

typedefintstatus;

typedefstruct{

elemtype2*top;

elemtype2*base;

intsize;

}stack2;

statusinitstack2(stack2&da){da.base=(elemtype2*)malloc(max_size_stack*sizeof(elemtype2));if(!

da.base)cout<<"操作失败,程序执行无效!

!

!

!

!

!

"<

精彩文档

实用标准文案

da.size=max_size_stack;

returnok;

}

statuspop2(stack2&da,elemtype2&e){

if(da.base==da.top)returnerror;

e=*(--da.top);

returnok;

}

statuspush2(stack2&da,elemtype2e){if(da.top-da.base>=da.size){

da.base=(elemtype2*)realloc(da.base,(da.size+incre)*sizeof(elemtype2));

!

!

!

!

!

!

"<

if(!

da.base)cout<<"操作失败,程序执行无效

da.top=da.base+da.size;

da.size+=incre;

}

*da.top++=e;

returnok;

}

intcoun(elemtype2e1,elemtype2e2,charcch){switch(cch){case'+':

returne1+e2;

精彩文档

实用标准文案

case'-':

returne1-e2;

case'*':

returne1*e2;

case'/':

if(e2==0)returnerror;elsereturne1/e2;

case'#':

returnok;break;

default:

returnerror;

}

}

voidmain(){

charcch;

inti,count=0,e1,e2;

stack2da;

initstack2(da);

cout<<"请输入表达式的逆波兰式:

(#表结束)"<

for(cch='1',i=0;cch!

='#'&&i<20;i++){

cin>>cch;

if(cch!

='+'&&cch!

='-'&&cch!

='*'&&cch!

='/'&&cch!

='#')

push2(da,cch-48);

elseif(cch!

='#'){

pop2(da,e2);pop2(da,e1);

if(coun(e1,e2,cch)==-100){

cout<<"表达是不合法:

"<

cout<<"操作失败,程序执行无效!

!

!

!

!

!

"<

精彩文档

实用标准文案

else

push2(da,coun(e1,e2,cch));

else{

pop2(da,e1);

cout<<"表达式的值为:

"<

}

}

}

运行结果:

 

3.14若以1234作为双端队列的输入序列,试分别求出满足以下条件的输出序列:

(1)能由输入受限的双端队列得到,但不能由输出受限的双端队列得到的输出序列。

(2)能由输出受限的双端队列得到,但不能由输入受限的双端队列得到的输出序列。

(3)既不能由输入受限的双端队列得到,也不能由输出受限的双端队列得到的输出序列。

解:

1,2,3,4

输入受限

1

2

3

4

精彩文档

实用标准文案

4和2不可相连

1,2,3,4

输出受限

1

2

1和2不可分开

4在1,3或2,3之间

由上分析可知:

输出受限不可得到:

1243,3412,1342,1432,3142,4132,1324,1423,

2143,3421,2341,2431,3241,4231,2314,2413.输入受限不可得到:

1243,3241,

1423,3421

3.29如果希望循环队列中的元素都能得到利用,则需设置一个标志域tag,并以tag的值为0和1来区分,尾指针和头指针值相同时的队列状态是“空”还是“满”。

试编写与此结构相应的入队列和出队列的算法,并从时间和空间角度讨论设标志和不设标志这两种方法的使用范围(如当循环队列容量较小而队列中每个元素占的空间较多时,哪一种方法较好)。

解:

程序源代码:

#include

#include

精彩文档

实用标准文案

#definemaxqsize5

#defineok1

#defineerror0

typedefintqelemtype;

typedefintstatus;

typedefstruct{

qelemtype*base;

intfront;

intrear;

inttag;

}squeue;

statusinitqueue(squeue&sq){

sq.base=(qelemtype*)malloc(maxqsize*sizeof(qelemtype));if(!

sq.base)exit(-2);

sq.front=sq.rear=0;

sq.tag=0;

returnok;

}

statusenqueue(squeue&sq,qelemtypee){

if(sq.rear==sq.front&&sq.tag)returnerror;sq.base[sq.rear]=e;

sq.rear=(sq.rear+1)%maxqsize;

精彩文档

实用标准文案

if(sq.rear==sq.front)sq.tag=1;

returnok;

}

statusdequeue(squeue&sq,qelemtype&e){

if(sq.rear==sq.front&&!

sq.tag)returnerror;e=sq.base[sq.front];

sq.front=(sq.front+1)%maxqsize;

if(sq.tag==1)sq.tag=0;

returnok;

}

voidmain(){

squeuesq;

qelemtypee;

inti;

initqueue(sq);

cout<<"请输入队列元素:

"<

cin>>e;

"<

"<

if(enqueue(sq,e))cout<<"元素已插入cout<<"请输入队列元素:

"<>e;

if(enqueue(sq,e))cout<<"元素已插入cout<<"请输入队列元素:

"<

精彩文档

实用标准文案

cin>>e;

if(enqueue(sq,e))cout<<"元素已插入"<

if(dequeue(sq,e))cout<<"队头元素:

"<

cout<<"队列中元素为:

"<

for(;dequeue(sq,e);)

cout<

cout<

运行结果:

3.30假设将循环队列定义为:

以域变量rear和length分别指示循环队列中队尾元素的位置和内含元素的个数。

试给出此循环队列的队满条件,并写出相应的入队列和出队列的算法出队列的算法中要返回队头元素)解:

程序源代码:

#include#include#definemax3

精彩文档

实用标准文案

#defineok1

#defineerror0

typedefintstatus;

typedefintselemtype;

typedefstruct{

selemtype*base;

intrear;

intlength;

}squeue;

statusinitqueue(squeue&sq){

sq.base=(selemtype*)malloc(max*sizeof(selemtype));if(!

sq.base)exit(-2);

sq.rear=0;

sq.length=0;

returnok;

}

statusenqueue(squeue&sq,selemtypee){if(sq.length>=max)returnerror;sq.base[sq.rear]=e;

sq.rear=(sq.rear+1)%max;

sq.length++;

returnok;

精彩文档

实用标准文案

}

statusdequeue(squeue&sq,selemtype&e){

if(sq.length<=0)returnerror;

e=sq.base[(sq.rear+max-sq.length)%max];

sq.length--;

returnok;

}

voidmain(){

squeuesq;

selemtypee;

initqueue(sq);

cout<<"请输入队列元素:

"<

cin>>e;

if(enqueue(sq,e))cout<<"元素已插入"<

elsecout<<"队列已满元素未被插入"<

"<

cin>>e;

if(enqueue(sq,e))cout<<"元素已插入"<

elsecout<<"队列已满元素未被插入"<

"<

cin>>e;

if(enqueue(sq,e))cout<<"元素已插入"<

精彩文档

实用标准文案

elsecout<<"队列已满元素未被插入"<

cout<<"请输入队列元素:

"<

cin>>e;

if(enqueue(sq,e))cout<<"元素已插入"<

elsecout<<"队列已满元素未被插入"<

if(dequeue(sq,e))cout<<"队头元素:

"<

cout<<"队列中元素为:

"<

for(;dequeue(sq,e);)cout<

cout<

}

运行结果:

3.31假设称正读和反读都相同的字符序列为“回文”,例如,‘abba'和‘abcba'是回文,

abcde'和‘ababab'则不是回文。

试写一个算法判别读入的一个以‘@'为结束符的字符序列是否是“回文”解:

精彩文档

实用标准文案

程序源代码:

#include

#include

#definemax10

typedefcharelemtype;

typedefstruct{

elemt

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2