1
{p->top=p->top+1;/*栈顶+1*/
p->stack[p->top]=x;}/*数据入栈*/
}
/*出栈函数*/
ElemTypePop(SqStack*p)
{x=p->stack[p->top];/*将栈顶元素赋给x*/
p->top=p->top-1;}/*栈顶-1*/
/*获取栈顶元素函数*/
ElemTypeGetTop(SqStack*p)
{x=p->stack[p->top];}
/*遍历顺序栈函数*/
voidOutStack(SqStack*p)
{for(i=p->top;i>=0;i--)
printf("第%d个数据元素是:
%6d\n",i,p->stack[i]);}
/*置空顺序栈函数*/
voidsetEmpty(SqStack*p)
{p->top=-1;}
2./*定义链队列*/
typedefstructQnode
{ElemTypedata;
structQnode*next;
}Qnodetype;
typedefstruct
{Qnodetype*front;
Qnodetype*rear;
}Lqueue;
/*初始化并建立链队列函数*/
voidcreat(Lqueue*q)
{h=(Qnodetype*)malloc(sizeof(Qnodetype));/*初始化申请空间*/h->next=NULL;
q->front=h;
q->rear=h;
for(i=1;i<=n;i++)*利用循环快速输入数据*/
{scanf("%d",&x);
Lappend(q,x);}/*利用入链队列函数快速输入数据*/}
/*入链队列函数*/
voidLappend(Lqueue*q,intx)
{s->data=x;
s->next=NULL;
q->rear->next=s;
q->rear=s;}
/*出链队列函数*/
ElemTypeLdelete(Lqueue*q)
{p=q->front->next;
q->front->next=p->next;
if(p->next==NULL)
q->rear=q->front;
x=p->data;
free(p);}/*释放空间*/
/*遍历链队列函数*/
voiddisplay(Lqueue*q)
{while(p!
=NULL)/*利用条件判断是否到队尾*/
{printf("%d-->",p->data);
p=p->next;
}
}
五、思考与提高
1.读栈顶元素的算法与退栈顶元素的算法有何区别?
2.如果一个程序中要用到两个栈,为了不发生上溢错误,就必须给每个栈预先分配一个足够大的存储空间。
若每个栈都预分配过大的存储空间,势必会造成系统空间紧张。
如何解决这个问题?
(1)链栈只有一个top指针,对于链队列,为什么要设计一个头指针和一个尾指针?
(2)一个程序中如果要用到两个栈时,可通过两个栈共享一维数组来实现。
即双向栈共享邻接空间。
如果一个程序中要用到两个队列,能否实现?
如何实现?
六、完整参考程序
1.栈的顺序表示和实现
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
typedefintStatus;
typedefintSElemType;
//-----栈的顺序存储表示-----
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefstruct{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
StatusInitStack(SqStack&S);
StatusDestroyStack(SqStack&S);
StatusStackDisplay(SqStack&S);
StatusGetTop(SqStackS,SElemType&e);
StatusPush(SqStack&S,SElemTypee);
StatusPop(SqStack&S,SElemType&e);
StatusStackEmpty(SqStackS);
StatusInitStack(SqStack&S){//构造一个空栈S
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);//存储分配失效
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}//InitStack
StatusDestroyStack(SqStack&S){//销毁栈S
if(S.base)free(S.base);
S.top=S.base=NULL;
returnOK;
}//InitStack
StatusStackDisplay(SqStack&S){//显示栈S
SElemType*p=S.base;
inti=0;
if(S.base==S.top){
printf("堆栈已空!
\n");
returnOK;
}
while(pprintf("[%d:
%d]",++i,*p++);
printf("\n");
returnOK;
}//StackDisplay
StatusGetTop(SqStackS,SElemType&e){
//若栈不空,则用e返回S的栈顶元素,
//并返回OK;否则返回ERROR
if(S.top==S.base)returnERROR;
e=*(S.top-1);
returnOK;
}//GetTop
StatusPush(SqStack&S,SElemTypee){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){//栈满,追加存储空间
S.base=(SElemType*)realloc(S.base,
(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);//存储分配失败
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
returnOK;
}//Push
StatusPop(SqStack&S,SElemType&e){
//若栈不为空,则删除S的栈顶元素,
//用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base)returnERROR;
e=*--S.top;
returnOK;
}//Pop
StatusStackEmpty(SqStackS){
//若S为空栈,则返回TRUE,否则返回FALSE。
if(S.top==S.base)returnTRUE;
elsereturnFALSE;
}//StackEmpty
voidmain(){
SqStackSt;
Statustemp;
intflag=1,ch;
inte;
printf("本程序实现顺序结构的堆栈的操作。
\n");
printf("可以进行入栈,出栈,取栈顶元素等操作。
\n");
InitStack(St);//初始化堆栈St
while(flag){
printf("请选择:
\n");
printf("1.显示栈中所有元素\n");
printf("2.入栈\n");
printf("3.出栈\n");
printf("4.取栈顶元素\n");
printf("5.退出程序\n");
scanf("%d",&ch);
switch(ch){
case1:
StackDisplay(St);
break;
case2:
printf("请输入要入栈的元素(一个整数):
");
scanf("%d",&e);//输入要入栈的元素
temp=Push(St,e);//入栈
if(temp!
=OK)printf("堆栈已满!
入栈失败!
\n");
else{
printf("成功入栈!
\n");//成功入栈
StackDisplay(St);
}
break;
case3:
temp=Pop(St,e);//出栈
if(temp==ERROR)printf("堆栈已空!
\n");
else{
printf("成功出栈一个元素:
%d\n",e);//成功出栈
StackDisplay(St);
}
break;
case4:
temp=GetTop(St,e);//取得栈顶元素
if(temp==ERROR)printf("堆栈已空!
\n");
elseprintf("栈顶元素是:
%d\n",e);//显示栈顶元素
break;
default:
flag=0;
printf("程序结束,按任意键退出!
\n");
getch();
}
}
DestroyStack(St);
}
2.队列的链式表示和实现
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
//Status是函数的类型,其值是函数结果状态代码typedefintStatus;
//ElemType是顺序表数据元素类型,此程序定义为int型typedefintQElemType;
//-----单链队列--队列的链式存储结构-----
typedefstructQNode{//定义结点结构
QElemTypedata;//数据域
structQNode*next;//指针域
}QNode,*QueuePtr;
typedefstructlinkqueue{//定义队列结构
QueuePtrfront;//队头指针
QueuePtrrear;//队尾指针
}LinkQueue;
StatusInitLinkQueue(LinkQueue&);//初始化一个队列StatusDestroyLinkQueue(LinkQueue&);//销毁一个队列
intLinkQueueLength(LinkQueue&Q);//队列的长度StatusEnLinkQueue(LinkQueue&,QElemType);//将一个元素入队列StatusDeLinkQueue(LinkQueue&,QElemType&);//将一个元素出队列StatusDisplayLinkQueue(LinkQueue);//显示队列中所有元素
voidmain(){
LinkQueueLQ;
QElemTypee;
intflag=1,ch,len;
Statustemp;
printf("本程序实现链式结构队列的操作。
\n");
printf("可以进行入队列、出队列等操作。
\n");
InitLinkQueue(LQ);//初始化队列
while(flag){
printf("请选择:
\n");
printf("1.显示队列所有元素\n");
printf("2.入队列\n");
printf("3.出队列\n");
printf("4.求队列的长度\n");
printf("5.退出程序\n");
scanf("%d",&ch);
switch(ch){
case1:
DisplayLinkQueue(LQ);//显示队列中所有元素
break;
case2:
printf("请输入要人队的元素(一个整数):
");
scanf("%d",&e);//输入要入队列的字符
EnLinkQueue(LQ,e);//入队列
DisplayLinkQueue(LQ);
break;
case3:
temp=DeLinkQueue(LQ,e);//出队列
if(temp==OK){
printf("出队一个元素:
%d\n",e);
DisplayLinkQueue(LQ);
}
elseprintf("队列为空!
\n");
break;
case4:
len=LinkQueueLength(LQ);
printf("队列的长度为:
%d\n",len);
break;
default:
flag=0;
printf("程序运行结束,按任意键退出!
\n");
getch();
}
}
}
StatusInitLinkQueue(LinkQueue&Q){//队列初始化
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));//生成一个头结点,并把首尾指针指向头结点
Q.front->next=NULL;
returnOK;
}
StatusDestroyLinkQueue(LinkQueue&Q){//销毁一个队列
QueuePtrp;
QElemTypee;
while(Q.front!
=Q.rear)
DeLinkQueue(Q,e);
free(Q.front);
Q.front=Q.rear=NULL;
returnOK;
}
intLinkQueueLength(LinkQueue&Q){//队列的长度
inti=0;
QueuePtrp=Q.front;
while(p!
=Q.rear){
++i;
p=p->next;
}
returni;
}
StatusEnLinkQueue(LinkQueue&Q,QElemTypee){//入队列
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));//生成一个新结点
p->data=e;//赋值
p->next=NULL;
Q.rear->next=p;//插入至队列尾
Q.rear=p;//修改队尾指针
returnOK;
}
StatusDeLinkQueue(LinkQueue&Q,QElemType&e){//出队列
QueuePtrp;
if(Q.front==Q.rear)returnERROR;//判断队列是否已空,已空返回ERROR
p=Q.front->next;//p指向队列中第一个元素
e=p->data;//取得该元素值
Q.front->next=p->next;//修改队首指针
if(Q.rear==p)Q.rear=Q.front;//若队列已空,把队尾指针指向头结点
returnOK;//成功出队列,返回OK}
StatusDisplayLinkQueue(LinkQueueQ){//显示队列中所有元素
QueuePtrp;
inti=0;
p=Q.front->next;
if(p==NULL)printf("队列为空!
\n");//队列为空
else{
while(p){//否则显示队列中所有元素
printf("[%d:
%d]",++i,p->data);
p=p->next;
}
printf("\n");
}
returnOK;
}