用顺序结构表示栈并实现栈的各种基本操作.docx
- 文档编号:10864302
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:21
- 大小:20.37KB
用顺序结构表示栈并实现栈的各种基本操作.docx
《用顺序结构表示栈并实现栈的各种基本操作.docx》由会员分享,可在线阅读,更多相关《用顺序结构表示栈并实现栈的各种基本操作.docx(21页珍藏版)》请在冰豆网上搜索。
用顺序结构表示栈并实现栈的各种基本操作
栈的顺序表示和实现
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->top {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;} 【参考程序】 #include #include #defineMAXNUM20 #defineElemTypeint /*定义顺序栈的存储结构*/ typedefstruct {ElemTypestack[MAXNUM]; inttop; }SqStack; /*初始化顺序栈*/ voidInitStack(SqStack*p) {if(! p) printf("Eorror"); p->top=-1; } /*入栈*/ voidPush(SqStack*p,ElemTypex) {if(p->top {p->top=p->top+1; p->stack[p->top]=x; } else printf("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->top<0) 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;//当前的栈顶指向原栈的next free(p);//释放 } /*取栈顶元素函数*/ ElemtypeStackTop(LinkStack*s) {returns->top->data;} /*遍历链栈函数*/ voidDisp(LinkStack*s) {while(p! =NULL) {printf("%d\n",p->data); p=p->next; } } 【参考程序】 #include"stdio.h" #include"malloc.h" #include"stdlib.h" typedefintElemtype; 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;//当前的栈顶指向原栈的next free(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("输入将要压入链栈的数据的个数: n="); scanf("%d",&n); printf("依次将%d个数据压入链栈: \n",n); for(i=1;i<=n;i++) {scanf("%d",&a); pushLstack(s,a); } Disp(s); }break; case3: {printf("\n出栈操作开始! \n"); printf("输入将要出栈的数据个数: m="); scanf("%d",&m); for(i=1;i<=m;i++) {printf("\n第%d次出栈的数据是: %d",i,popLstack(s));} Disp(s); }break; case4: {printf("\n\n链栈的栈顶元素为: %d\n",StackTop(s)); printf("\n"); }break; case5: {setEmpty(s); Disp(s); }break; case6: exit(0); } }while(cord<=6); } 【思考与提高】 (1)栈的两种存储结构在判别栈空与栈满时,所依据的条件有何不同? (2)在程序中同时使用两个以上的栈时,使用顺序栈共享邻接空间则很难实现,能否通过链栈来方便地实现? 如何实现? 实验三: 队列的顺序表示和实现 【实验内容与要求】 编写一个程序实现顺序队列的各种基本运算,并在此基础上设计一个主程序,完成如下功能: (1)初始化队列 (2)建立顺序队列 (3)入队 (4)出队 (5)判断队列是否为空 (6)取队头元素 (7)遍历队列 【知识要点】 队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表。 入队时,将新元素插入rear所指的位置,然后将rear加1。 出队时,删去front所指的元素,然后将front加1并返回被删元素。 顺序队列中的溢出现象: (1)"下溢"现象。 当队列为空时,做出队运算产生的溢出现象。 “下溢”是正常现象,常用作程序控制转移的条件。 (2)"真上溢"现象。 当队列满时,做进栈运算产生空间溢出的现象。 “真上溢”是一种出错状态,应设法避免。 (3)"假上溢"现象。 由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。 当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。 该现象称为"假上溢"现象。 注意: (1)当头尾指针相等时,队列为空。 (2)在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。 【实现提示】 /*定义队列*/ typedefstruct {Elemtypequeue[MAXNUM]; intfront; intrear; }sqqueue; /*队列初始化函数*/ intinitQueue(sqqueue*q) {q=(sqqueue*)malloc(sizeof(sqqueue));/*初始化申请空间*/ q->front=-1; q->rear=-1; } /*入队函数*/ intappend(sqqueue*q,Elemtypex) {q->rear++; q->queue[q->rear]=x;} /*出队函数*/ ElemtypeDelete(sqqueue*q) {x=q->queue[++q->front];} /*判断队列是否为空函数*/ intEmpty(sqqueue*q) {if(q->front==q->rear)returnTRUE;} /*取队头元素函数*/ intgethead(sqqueue*q) {return(q->queue[q->front+1]);} /*遍历队列函数*/ voiddisplay(sqqueue*q) {while(s {s=s+1; printf("%d<-",q->queue[s]);} } /*建立顺序队列函数*/ voidSetsqqueue(sqqueue*q) {for(i=0;i {scanf("%d",&m); append(q,m);}}/*利用入队函数快速输入数据*/ 【参考程序】 #include #include #defineMAXNUM100 #defineElemtypeint #defineTRUE1 #defineFALSE0 typedefstruct {Elemtypequeue[MAXNUM]; intfront; intrear; }sqqueue; /*队列初始化*/ intinitQueue(sqqueue*q) {if(! q)returnFALSE; q->front=-1; q->rear=-1; returnTRUE; } /*入队*/ intappend(sqqueue*q,Elemtypex) {if(q->rear>=MAXNUM-1)returnFALSE; q->rear++; q->queue[q->rear]=x; returnTRUE; } /*出队*/ ElemtypeDelete(sqqueue*q) {Elemtypex; if(q->front==q->rear)return0; x=q->queue[++q->front]; returnx; } /*判断队列是否为空*/ intEmpty(sqqueue*q) {if(q->front==q->rear)returnTRUE; returnFALSE; } /*取队头元素*/ intgethead(sqqueue*q) {if(q->front==q->rear)return0; return(q->queue[q->front+1]); } /*遍历队列*/ voiddisplay(sqqueue*q) {ints; s=q->front; if(q->front==q->rear) printf("队列空! \n"); else {printf("\n顺序队列依次为: "); while(s {s=s+1; printf("%d<-",q->queue[s]); } printf("\n"); printf("顺序队列的队尾元素所在位置: rear=%d\n",q->rear); printf("顺序队列的队头元素所在位置: front=%d\n",q->front); } } /*建立顺序队列*/ voidSetsqqueue(sqqueue*q) {intn,i,m; printf("\n请输入将要入顺序队列的长度: "); scanf("%d",&n); printf("\n请依次输入入顺序队列的元素值: \n"); for(i=0;i {scanf("%d",&m); append(q,m);} } main() {sqqueue*head; intx,y,z,select; head=(sqqueue*)malloc(sizeof(sqqueue)); do{printf("\n第一次使用请初始化! \n"); printf("\n请选择操作(1--7): \n"); printf("===================================\n"); printf("1初始化\n"); printf("2建立顺序队列\n"); printf("3入队\n"); printf("4出队\n"); printf("5判断队列是否为空\n"); printf("6取队头元素\n"); printf("7遍历队列\n"); printf("===================================\n"); scanf("%d",&select); switch(select) {case1: {initQueue(head); printf("已经初始化顺序队列! \n"); break; } case2: {Setsqqueue(head); printf("\n已经建立队列! \n"); display(head); break; } case3: {printf("请输入队
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 顺序 结构 表示 实现 各种 基本 操作
![提示](https://static.bdocx.com/images/bang_tan.gif)