栈的顺序表示和实现2.2基础实验2.2.1实验目的(1)掌握栈的顺序表示和实现(2)掌握栈的链式表示和实现(3)掌握队列的顺序表示和实现(4)掌握队列的链式表示和实现2.2.2实验内容实验一:栈的顺序表示和实现【实验内容与要求】编写一个程序实现顺序栈的各种基本运算,并在此基础上设计一个主程序,完成如下功能:(1)初始化顺序栈(2)插入元素(3)删除栈顶元素(4)取栈顶元素(5)遍历顺序栈(6)置空顺序栈【知识要点】栈的顺序存储结构简称为顺序栈,它是运算受限的顺序表。对于顺序栈,入栈时,首先判断栈是否为满,栈满的条件为:p-top==MAXNUM-1,栈满时,不能入栈;否则出现空间溢出,引起错误,这种现象称为上溢。出栈和读栈顶元素操作,先判栈是否为空,为空时不能操作,否则产生错误。通常栈空作为一种控制转移的条件。注意:(1)顺序栈中元素用向量存放(2)栈底位置是固定不变的,可设置在向量两端的任意一个端点(3)栈顶位置是随着进栈和退栈操作而变化的,用一个整型量top(通常称top为栈顶指针)来指示当前栈顶位置【实现提示】/*定义顺序栈的存储结构*/typedefstruct{ElemTypestack[MAXNUM];inttop;}SqStack;/*初始化顺序栈函数*/voidInitStack(SqStack*p){q=(SqStack*)malloc(sizeof(SqStack)/*申请空间*/)/*入栈函数*/voidPush(SqStack*p,ElemTypex){if(p-topMAXNUM-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;}【参考程序】#includestdio.h#includestdlib.h#defineMAXNUM20#defineElemTypeint/*定义顺序栈的存储结构*/typedefstruct{ElemTypestack[MAXNUM];inttop;}SqStack;/*初始化顺序栈*/voidInitStack(SqStack*p){if(!p)printf(Eorror);p-top=-1;}/*入栈*/voidPush(SqStack*p,ElemTypex){if(p-topMAXNUM-1){p-top=p-top+1;p-stack[p-top]=x;}elseprintf(Overflow!\n);}/*出栈*/ElemTypePop(SqStack*p){ElemTypex;if(p-top!=0){x=p-stack[p-top];printf(以前的栈顶数据元素%d已经被删除!\n,p-stack[p-top]);p-top=p-top-1;return(x);}else{printf(Underflow!\n);return(0);}}/*获取栈顶元素*/ElemTypeGetTop(SqStack*p){ElemTypex;if(p-top!=0){x=p-stack[p-top];return(x);}else{printf(Underflow!\n);return(0);}}/*遍历顺序栈*/voidOutStack(SqStack*p){inti;printf(\n);if(p-top0)printf(这是一个空栈!);printf(\n);for(i=p-top;i=0;i--)printf(第%d个数据元素是:%6d\n,i,p-stack[i]);}/*置空顺序栈*/voidsetEmpty(SqStack*p){p-top=-1;}/*主函数*/main(){SqStack*q;inty,cord;ElemTypea;do{printf(\n);printf(第一次使用必须初始化!\n);printf(\n);printf(\n主菜单\n);printf(\n1初始化顺序栈\n);printf(\n2插入一个元素\n);printf(\n3删除栈顶元素\n);printf(\n4取栈顶元素\n);printf(\n5置空顺序栈\n);printf(\n6结束程序运行\n);printf(\n--------------------------------\n);printf(请输入您的选择(1,2,3,4,5,6));scanf(%d,&cord);printf(\n);switch(cord){case1:{q=(SqStack*)malloc(sizeof(SqStack));InitStack(q);OutStack(q);}break;case2:{printf(请输入要插入的数据元素:a=);scanf(%d,&a);Push(q,a);OutStack(q);}break;case3:{Pop(q);OutStack(q);}break;case4:{y=GetTop(q);printf(\n栈顶元素为:%d\n,y);OutStack(q);}break;case5:{setEmpty(q);printf(\n顺序栈被置空!\n);OutStack(q);}break;case6:exit(0);}}while(cord=6);}【思考与提高】(1)读栈顶元素的算法与退栈顶元素的算法有何区别?(2)如果一个程序中要用到两个栈,为了不发生上溢错误,就必须给每个栈预先分配一个足够大的存储空间。若每个栈都预分配过大的存储空间,势必会造成系统空间紧张。如何解决这个问题?实验二:栈的链式表示和实现【实验内容与要求】编写一个程序实现链栈的各种基本运算,并在此基础上设计一个主程序,完成如下功能:(1)初始化链栈(2)链栈置空(3)入栈(4)出栈(5)取栈顶元素(6)遍历链栈【知识要点】链栈是没有附加头结点的运算受限的单链表。栈顶指针就是链表的头指针。注意:(1)LinkStack结构类型的定义可以方便地在函数体中修改top指针本身(2)若要记录栈中元素个数,可将元素个数属性放在LinkStack类型中定义。(3)链栈中的结点是动态分配的,所以可以不考虑上溢。【实现提示】typedefintElemtype;typedefstructstacknode{Elemtypedata;stacknode*next;}StackNode;/*定义链栈*/typedefstruct{stacknode*top;//栈顶指针}LinkStack;/*初始化链栈函数*/voidInitStack(LinkStack*s){s=(LinkStack*)malloc(sizeof(LinkStack));/*初始化申请空间*/s-top=NULL;}/*链栈置空函数*/voidsetEmpty(LinkStack*s){s-top=NULL;}/*入栈函数*/voidpushLstack(LinkStack*s,Elemtypex){p=(StackNode*)malloc(sizeof(StackNode));//建立一个节点。p-data=x;p-next=s-top;//指向栈顶。s-top=p;//插入}/*出栈函数*/ElemtypepopLstack(LinkStack*s){x=p-data;s-top=p-next;//当前的栈顶指向原栈的nextfree(p);//释放}/*取栈顶元素函数*/ElemtypeStackTop(LinkStack*s){returns-top-data;}/*遍历链栈函数*/voidDisp(LinkStack*s){while(p!=NULL){printf(%d\n,p-data);p=p-next;}}【参考程序】#includestdio.h#includemalloc.h#includestdlib.htypedefintElemtype;typedefstructstacknode{Elemtypedata;stacknode*next;}StackNode;typedefstruct{stacknode*top;//栈顶指针}LinkStack;/*初始化链栈*/voidInitStack(LinkStack*s){s-top=NULL;printf(\n已经初始化链栈!\n);}/*链栈置空*/voidsetEmpty(LinkStack*s){s-top=NULL;printf(\n链栈被置空!\n);}/*入栈*/voidpushLstack(LinkStack*s,Elemtypex){StackNode*p;p=(StackNode*)malloc(sizeof(StackNode));//建立一个节点。p-data=x;p-next=s-top;//由于是在栈顶pushLstack,所以要指向栈顶。s-top=p;//插入}/*出栈*/ElemtypepopLstack(LinkStack*s){Elemtypex;StackNode*p;p=s-top;//指向栈顶if(s-top==0){printf(\n栈空,不能出栈!\n);exit(-1);}x=p-data;s-top=p-next;//当前的栈顶指向原栈的nextfree(p);//释放returnx;}/*取栈顶元素*/ElemtypeStackTop(LinkStack*s){if(s-top==0){printf(\n链栈空\n);exit(-1);}returns-top-data;}/*遍历链栈*/voidDisp(LinkStack*s){printf(\n链栈中的数据为:\n);printf(=======================================\n);StackNode*p;p=s-top;while(p!=NULL){printf(%d\n,p-data);p=p-next;}printf(=======================================\n);}voidmain(){printf(=================链栈操作=================\n\n);inti,m,n,a;LinkStack*s;s=(LinkStack*)malloc(sizeof(LinkStack));intcord;do{printf(\n);printf(第一次使用必须初始化!\n);printf(\n);printf(\n主菜单\n);printf(\n1初始化链栈\n);printf(\n2入栈\n);printf(\n3出栈\n);printf(\n4取栈顶元素\n);printf(\n5置空链栈\n);printf(\n6结束程序运行\n);printf(\n--------------------------------\n);printf(请输入您的选择(1,2,3,4,5,6));scanf(%d,&cord);printf(\n);switch(cord){case1:{InitStack(s);Disp(s);}break;case2:{printf(输入将要压入链栈的数