也就是说,若有1,2,3顺序入栈,不可能有3,1,2的出栈序列。
3.3voidsympthy(linklist*head,stack*s)
//判断长为n的字符串是否中心对称
{inti=1;linklist*p=head->next;
while(i<=n/2)//前一半字符进栈
{push(s,p->data);p=p->next;}
if(n%2!
==0)p=p->next;//奇数个结点时跳过中心结点
while(p&&p->data==pop(s))p=p->next;
if(p==null)printf(“链表中心对称”);
elseprintf(“链表不是中心对称”);
}//算法结束
3.4
intmatch()
//从键盘读入算术表达式,本算法判断圆括号是否正确配对
(inits;//初始化栈s
scanf(“%c”,&ch);
while(ch!
=’#’)//’#’是表达式输入结束符号
switch(ch)
{case’(’:
push(s,ch);break;
case’)’:
if(empty(s)){printf(“括号不配对”);exit(0);}
pop(s);
}
if(!
empty(s))printf(“括号不配对”);
elseprintf(“括号配对”);
}//算法结束
3.5
typedefstruct//两栈共享一向量空间
{ElemTypev[m];//栈可用空间0—m-1
inttop[2]//栈顶指针
}twostack;
intpush(twostack*s,inti,ElemTypex)
//两栈共享向量空间,i是0或1,表示两个栈,x是进栈元素,
//本算法是入栈操作
{if(abs(s->top[0]-s->top[1])==1)return(0);//栈满
else{switch(i)
{case0:
s->v[++(s->top)]=x;break;
case1:
s->v[--(s->top)]=x;break;
default:
printf(“栈编号输入错误”);return(0);
}
return
(1);//入栈成功
}
}//算法结束
ElemTypepop(twostack*s,inti)
//两栈共享向量空间,i是0或1,表示两个栈,本算法是退栈操作
{ElemTypex;
if(i!
=0&&i!
=1)return(0);//栈编号错误
else{switch(i)
{case0:
if(s->top[0]==-1)return(0);//栈空
elsex=s->v[s->top--];break;
case1:
if(s->top[1]==m)return(0);//栈空
elsex=s->v[s->top++];break;
default:
printf(“栈编号输入错误”);return(0);
}
return(x);//退栈成功
}
}//算法结束
ElemTypetop(twostack*s,inti)
//两栈共享向量空间,i是0或1,表示两个栈,本算法是取栈顶元素操作
{ElemTypex;
switch(i)
{case0:
if(s->top[0]==-1)return(0);//栈空
elsex=s->v[s->top];break;
case1:
if(s->top[1]==m)return(0);//栈空
elsex=s->v[s->top];break;
default:
printf(“栈编号输入错误”);return(0);
}
return(x);//取栈顶元素成功
}//算法结束
3.6
voidAckerman(intm,intn)
//Ackerman函数的递归算法
{if(m==0)return(n+1);
elseif(m!
=0&&n==0)return(Ackerman(m-1,1);
elsereturn(Ackerman(m-1,Ackerman(m,n-1))
}//算法结束
3.7
(1)linklist*init(linklist*q)
//q是以带头结点的循环链表表示的队列的尾指针,本算法将队列置空
{q=(linklist*)malloc(sizeof(linklist));//申请空间,不判断空间溢出
q->next=q;
return(q);
}//算法结束
(2)linklist*enqueue(linklist*q,ElemTypex)
//q是以带头结点的循环链表表示的队列的尾指针,本算法将元素x入队
{s=(linklist*)malloc(sizeof(linklist));//申请空间,不判断空间溢出
s->next=q->next;//将元素结点s入队列
q->next=s;
q=s;//修改队尾指针
return(q);
}//算法结束
(3)linklist*delqueue(linklist*q)
//q是以带头结点的循环链表表示的队列的尾指针,这是出队算法
{if(q==q->next)return(null);//判断队列是否为空
else{linklist*s=q->next->next;//s指向出队元素
if(s==q)q=q->next;//若队列中只一个元素,置空队列
elseq->next->next=s->next;//修改队头元素指针
free(s);//释放出队结点
}
return(q);
}//算法结束。
算法并未返回出队元素
3.8
typedefstruct
{ElemTypedata[m];//循环队列占m个存储单元
intfront,rear;//front和rear为队头元素和队尾元素的指针
//约定front指向队头元素的前一位置,rear指向队尾元素
}sequeue;
intqueuelength(sequeue*cq)
//cq为循环队列,本算法计算其长度
{return(cq->rear-cq->front+m)%m;
}//算法结束
3.9
typedefstruct
{ElemTypesequ[m];//循环队列占m个存储单元
intrear,quelen;//rear指向队尾元素,quelen为元素个数
}sequeue;
(1)intempty(sequeue*cq)
//cq为循环队列,本算法判断队列是否为空
{return(cq->quelen==0?
1:
0);
}//算法结束
(2)sequeue*enqueue(sequeue*cq,ElemTypex)
//cq是如上定义的循环队列,本算法将元素x入队
{if(cq->quelen==m)return(0);//队满
else{cq->rear=(cq->rear+1)%m;//计算插入元素位置
cq->sequ[cq->rear]=x;//将元素x入队列
cq->quelen++;//修改队列长度
}
return(cq);
}//算法结束
ElemTypedelqueue(sequeue*cq)
//cq是以如上定义的循环队列,本算法是出队算法,且返回出队元素
{if(cq->quelen==0)return(0);//队空
else{intfront=(cq->rear-cq->quelen+1+m)%m;//出队元素位置
cq->quelen--;//修改队列长度
return(cq->sequ[front]);//返回队头元素
}
}//算法结束
第四章串(参考答案)
在以下习题解答中,假定使用如下类型定义:
#defineMAXSIZE1024
typedefstruct
{chardata[MAXSIZE];
intcurlen;//curlen表示终端结点在向量中的位置
}seqstring;
typedefstructnode
{chardata;
structnode*next;
}links