数据结构课后习题解答第三章 栈与队列.docx

上传人:b****6 文档编号:9015463 上传时间:2023-02-02 格式:DOCX 页数:10 大小:18.38KB
下载 相关 举报
数据结构课后习题解答第三章 栈与队列.docx_第1页
第1页 / 共10页
数据结构课后习题解答第三章 栈与队列.docx_第2页
第2页 / 共10页
数据结构课后习题解答第三章 栈与队列.docx_第3页
第3页 / 共10页
数据结构课后习题解答第三章 栈与队列.docx_第4页
第4页 / 共10页
数据结构课后习题解答第三章 栈与队列.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

数据结构课后习题解答第三章 栈与队列.docx

《数据结构课后习题解答第三章 栈与队列.docx》由会员分享,可在线阅读,更多相关《数据结构课后习题解答第三章 栈与队列.docx(10页珍藏版)》请在冰豆网上搜索。

数据结构课后习题解答第三章 栈与队列.docx

数据结构课后习题解答第三章栈与队列

第三章栈与队列

3.15

typedefstruct{

                   Elemtype*base[2];

                   Elemtype*top[2];

                 }BDStacktype;//双向栈类型

StatusInit_Stack(BDStacktype&tws,intm)//初始化一个大小为m的双向栈tws

{

  tws.base[0]=(Elemtype*)malloc(sizeof(Elemtype));

  tws.base[1]=tws.base[0]+m;

  tws.top[0]=tws.base[0];

  tws.top[1]=tws.base[1];

  returnOK;

}//Init_Stack

Statuspush(BDStacktype&tws,inti,Elemtypex)//x入栈,i=0表示低端栈,i=1表示高端栈

{

  if(tws.top[0]>tws.top[1])returnOVERFLOW;//注意此时的栈满条件

  if(i==0)*tws.top[0]++=x;

  elseif(i==1)*tws.top[1]--=x;

  elsereturnERROR;

  returnOK;

}//push

Statuspop(BDStacktype&tws,inti,Elemtype&x)//x出栈,i=0表示低端栈,i=1表示高端栈

{

  if(i==0)

  {

    if(tws.top[0]==tws.base[0])returnOVERFLOW;

    x=*--tws.top[0];

  }

  elseif(i==1)

  {

    if(tws.top[1]==tws.base[1])returnOVERFLOW;

    x=*++tws.top[1];

  }

  elsereturnERROR;

  returnOK;

}//pop

3.16

voidTrain_arrange(char*train)//这里用字符串train表示火车,'H'表示硬席,'S'表示软席

{

  p=train;q=train;

  InitStack(s);

  while(*p)

  {

    if(*p=='H')push(s,*p);//把'H'存入栈中

    else*(q++)=*p;//把'S'调到前部

    p++;

  }

  while(!

StackEmpty(s))

  {

    pop(s,c);

    *(q++)=c;//把'H'接在后部

  }

}//Train_arrange

3.17

intIsReverse()//判断输入的字符串中'&'前和'&'后部分是否为逆串,是则返回1,否则返回0

{

  InitStack(s);

  while((e=getchar())!

='&')

    push(s,e);

  while((e=getchar())!

='@')

  {

    if(StackEmpty(s))return0;

    pop(s,c);

    if(e!

=c)return0;

  }

  if(!

StackEmpty(s))return0;

  return1;

}//IsReverse

3.18

StatusBracket_Test(char*str)//判别表达式中小括号是否匹配

{

  count=0;

  for(p=str;*p;p++)

  {

    if(*p=='(')count++;

    elseif(*p==')')count--;

    if(count<0)returnERROR;

  }

  if(count)returnERROR;//注意括号不匹配的两种情况

  returnOK;

}//Bracket_Test

3.19

StatusAllBrackets_Test(char*str)//判别表达式中三种括号是否匹配

{

  InitStack(s);

  for(p=str;*p;p++)

  {

    if(*p=='('||*p=='['||*p=='{')push(s,*p);

    elseif(*p==')'||*p==']'||*p=='}')

    {

      if(StackEmpty(s))returnERROR;

      pop(s,c);

      if(*p==')'&&c!

='(')returnERROR;

      if(*p==']'&&c!

='[')returnERROR;

      if(*p=='}'&&c!

='{')returnERROR;//必须与当前栈顶括号匹配

    }

  }//for

  if(!

StackEmpty(s))returnERROR;

  returnOK;

}//AllBrackets_Test

3.20

typedefstruct{

.            intx;

             inty;

           }coordinate;

voidRepaint_Color(intg[m][n],inti,intj,intcolor)//把点(i,j)相邻区域的颜色置换为color

{

  old=g[i][j];

  InitQueue(Q);

  EnQueue(Q,{I,j});

  while(!

QueueEmpty(Q))

  {

    DeQueue(Q,a);

 x=a.x;y=a.y;

    if(x>1)

      if(g[x-1][y]==old)

      {

        g[x-1][y]=color;

        EnQueue(Q,{x-1,y});//修改左邻点的颜色

      }

    if(y>1)

      if(g[x][y-1]==old)

      {

        g[x][y-1]=color;

        EnQueue(Q,{x,y-1});//修改上邻点的颜色

      }

    if(x

      if(g[x+1][y]==old)

      {

        g[x+1][y]=color;

        EnQueue(Q,{x+1,y});//修改右邻点的颜色

      }

    if(y

      if(g[x][y+1]==old)

      {

        g[x][y+1]=color;

        EnQueue(Q,{x,y+1});//修改下邻点的颜色

      }

  }//while

}//Repaint_Color

分析:

本算法采用了类似于图的广度优先遍历的思想,用两个队列保存相邻同色点的横坐标和纵坐标.递归形式的算法该怎么写呢?

3.21

voidNiBoLan(char*str,char*new)//把中缀表达式str转换成逆波兰式new

{

  p=str;q=new;//为方便起见,设str的两端都加上了优先级最低的特殊符号

  InitStack(s);//s为运算符栈

  while(*p)

  {

    if(*p是字母))*q++=*p;//直接输出

    else

    {

      c=gettop(s);

      if(*p优先级比c高)push(s,*p);

      else

      {

        while(gettop(s)优先级不比*p低)

        {

          pop(s,c);*(q++)=c;

        }//while

        push(s,*p);//运算符在栈内遵循越往栈顶优先级越高的原则

      }//else

    }//else

    p++;

  }//while

}//NiBoLan//参见编译原理教材

3.22

intGetValue_NiBoLan(char*str)//对逆波兰式求值

{

  p=str;InitStack(s);//s为操作数栈

  while(*p)

  {

    if(*p是数)push(s,*p);

    else

    {

      pop(s,a);pop(s,b);

      r=compute(b,*p,a);//假设compute为执行双目运算的过程

      push(s,r);

    }//else

    p++;

  }//while

  pop(s,r);returnr;

}//GetValue_NiBoLan

3.23

StatusNiBoLan_to_BoLan(char*str,stringtype&new)//把逆波兰表达式str转换为波兰式new

{

  p=str;Initstack(s);//s的元素为stringtype类型

  while(*p)

  {

    if(*p为字母)push(s,*p);

    else

    {

      if(StackEmpty(s))returnERROR;

      pop(s,a);

      if(StackEmpty(s))returnERROR;

      pop(s,b);

      c=link(link(*p,b),a);

      push(s,c);

    }//else

    p++;

  }//while

  pop(s,new);

  if(!

StackEmpty(s))returnERROR;

  returnOK;

}//NiBoLan_to_BoLan

分析:

基本思想见书后注释.本题中暂不考虑串的具体操作的实现,而将其看作一种抽象数据类型stringtype,对其可以进行连接操作:

c=link(a,b).

3.24

Statusg(intm,intn,int&s)//求递归函数g的值s

{

  if(m==0&&n>=0)s=0;

  elseif(m>0&&n>=0)s=n+g(m-1,2*n);

  elsereturnERROR;

  returnOK;

}//g

3.25

StatusF_recursive(intn,int&s)//递归算法

{

  if(n<0)returnERROR;

  if(n==0)s=n+1;

  else

  {

    F_recurve(n/2,r);

    s=n*r;

  }

  returnOK;

}//F_recursive

StatusF_nonrecursive(intn,ints)//非递归算法

{

  if(n<0)returnERROR;

  if(n==0)s=n+1;

  else

  {

    InitStack(s);//s的元素类型为struct{inta;intb;}

    while(n!

=0)

    {

      a=n;b=n/2;

      push(s,{a,b});

      n=b;

    }//while

    s=1;

    while(!

StackEmpty(s))

    {

      pop(s,t);

      s*=t.a;

    }//while

  }

  returnOK;

}//F_nonrecursive

3.26

floatSqrt_recursive(floatA,floatp,floate)//求平方根的递归算法

{

  if(abs(p^2-A)<=e)returnp;

  elsereturnsqrt_recurve(A,(p+A/p)/2,e);

}//Sqrt_recurve

floatSqrt_nonrecursive(floatA,floatp,floate)//求平方根的非递归算法

{

  while(abs(p^2-A)>=e)

    p=(p+A/p)/2;

  returnp;

}//Sqrt_nonrecursive

3.27

这一题的所有算法以及栈的变化过程请参见《数据结构(pascal版)》,作者不再详细写出.

3.28

voidInitCiQueue(CiQueue&Q)//初始化循环链表表示的队列Q

{

  Q=(CiLNode*)malloc(sizeof(CiLNode));

  Q->next=Q;

}//InitCiQueue

voidEnCiQueue(CiQueue&Q,intx)//把元素x插入循环链表表示的队列Q,Q指向队尾元素,Q->next指向头结点,Q->next->next指向队头元素

{

  p=(CiLNode*)malloc(sizeof(CiLNode));

  p->data=x;

  p->next=Q->next;//直接把p加在Q的后面

  Q->next=p;

  Q=p;  //修改尾指针

}

StatusDeCiQueue(CiQueue&Q,intx)//从循环链表表示的队列Q头部删除元素x

{

  if(Q==Q->next)returnINFEASIBLE;//队列已空

  p=Q->next->next;

  x=p->data;

  Q->next->next=p->next;

  free(p);

  returnOK;

}//DeCiQueue

3.29

StatusEnCyQueue(CyQueue&Q,intx)//带tag域的循环队列入队算法

{

  if(Q.front==Q.rear&&Q.tag==1)//tag域的值为0表示"空",1表示"满"

    returnOVERFLOW;

  Q.base[Q.rear]=x;

  Q.rear=(Q.rear+1)%MAXSIZE;

  if(Q.front==Q.rear)Q.tag=1;//队列满

}//EnCyQueue

StatusDeCyQueue(CyQueue&Q,int&x)//带tag域的循环队列出队算法

{

  if(Q.front==Q.rear&&Q.tag==0)returnINFEASIBLE;

  Q.front=(Q.front+1)%MAXSIZE;

  x=Q.base[Q.front];

  if(Q.front==Q.rear)Q.tag=1;//队列空

  returnOK;

}//DeCyQueue

分析:

当循环队列容量较小而队列中每个元素占的空间较多时,此种表示方法可以节约较多的存储空间,较有价值.

3.30

StatusEnCyQueue(CyQueue&Q,intx)//带length域的循环队列入队算法

{

  if(Q.length==MAXSIZE)returnOVERFLOW;

  Q.rear=(Q.rear+1)%MAXSIZE;

  Q.base[Q.rear]=x;

  Q.length++;

  returnOK;

}//EnCyQueue

StatusDeCyQueue(CyQueue&Q,int&x)//带length域的循环队列出队算法

{

  if(Q.length==0)returnINFEASIBLE;

  head=(Q.rear-Q.length+1)%MAXSIZE;//详见书后注释

  x=Q.base[head];

  Q.length--;

}//DeCyQueue

3.31

intPalindrome_Test()//判别输入的字符串是否回文序列,是则返回1,否则返回0

{

  InitStack(S);InitQueue(Q);

  while((c=getchar()!

='@')

  {

    Push(S,c);EnQueue(Q,c);//同时使用栈和队列两种结构

  }

  while(!

StackEmpty(S))

  {

    Pop(S,a);DeQueue(Q,b));

    if(a!

=b)returnERROR;

  }

  returnOK;

}//Palindrome_Test

3.32

voidGetFib_CyQueue(intk,intn)//求k阶斐波那契序列的前n+1项

{

  InitCyQueue(Q);//其MAXSIZE设置为k

  for(i=0;i

  Q.base[k-1]=1;//给前k项赋初值

  for(i=0;i

  for(i=k;i<=n;i++)

  {

    m=i%k;sum=0;

    for(j=0;j

    Q.base[m]=sum;//求第i项的值存入队列中并取代已无用的第一项

    printf("%d",sum);

  }

}//GetFib_CyQueue

3.33

StatusEnDQueue(DQueue&Q,intx)//输出受限的双端队列的入队操作

{

  if((Q.rear+1)%MAXSIZE==Q.front)returnOVERFLOW;//队列满

  avr=(Q.base[Q.rear-1]+Q.base[Q.front])/2;

  if(x>=avr)//根据x的值决定插入在队头还是队尾

  {

    Q.base[Q.rear]=x;

    Q.rear=(Q.rear+1)%MAXSIZE;

  }//插入在队尾

  else

  {

    Q.front=(Q.front-1)%MAXSIZE;

    Q.base[Q.front]=x;

  }//插入在队头

  returnOK;

}//EnDQueue

StatusDeDQueue(DQueue&Q,int&x)//输出受限的双端队列的出队操作

{

  if(Q.front==Q.rear)returnINFEASIBLE;//队列空

  x=Q.base[Q.front];

  Q.front=(Q.front+1)%MAXSIZE;

  returnOK;

}//DeDQueue

3.34

voidTrain_Rearrange(char*train)//这里用字符串train表示火车,'P'表示硬座,'H'表示硬卧,'S'表示软卧,最终按PSH的顺序排列

{

  r=train;

  InitDQueue(Q);

  while(*r)

  {

    if(*r=='P')

    {

      printf("E");

      printf("D");//实际上等于不入队列,直接输出P车厢

    }

    elseif(*r=='S')

    {

      printf("E");

      EnDQueue(Q,*r,0);//0表示把S车厢从头端入队列

    }

    else

    {

      printf("A");

      EnDQueue(Q,*r,1);//1表示把H车厢从尾端入队列

    }

  }//while

  while(!

DQueueEmpty(Q))

  {

    printf("D");

    DeDQueue(Q);

  }//while//从头端出队列的车厢必然是先S后H的顺序

}//Train_Rearrange 

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

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1