栈的操作实验报告.docx
- 文档编号:6554111
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:28
- 大小:23.80KB
栈的操作实验报告.docx
《栈的操作实验报告.docx》由会员分享,可在线阅读,更多相关《栈的操作实验报告.docx(28页珍藏版)》请在冰豆网上搜索。
栈的操作实验报告
栈的操作(实验报告)
栈和队列
3.1实验目的:
(1)熟悉栈的特点(先进后出)及栈的基本操作,如入栈、出栈等,掌握栈的基本操作
在栈的顺序存储结构和链式存储结构上的实现;
(2)熟悉队列的特点(先进先出)及队列的基本操作,如入队、出队等,掌握队列的基
本操作在队列的顺序存储结构和链式存储结构上的实现。
3.2实验要求:
(1)复习课本中有关栈和队列的知识;
(2)用C语言完成算法和程序设计并上机调试通过;
(3)撰写实验报告,给出算法思路或流程图和具体实现(源程序)、算法分析结果(包括
时间复杂度、空间复杂度以及算法优化设想)、输入数据及程序运行结果(必要时给出多种可能的输入数据和运行结果)。
3.3基础实验
[实验1]栈的顺序表示和实现
实验内容与要求:
编写一个程序实现顺序栈的各种基本运算,并在此基础上设计一个主程序,完成如下功能:
(1)初始化顺序栈
(2)插入元素
(3)删除栈顶元素
(4)取栈顶元素
(5)遍历顺序栈
(6)置空顺序栈
分析:
栈的顺序存储结构简称为顺序栈,它是运算受限的顺序表。
对于顺序栈,入栈时,首先判断栈是否为满,栈满的条件为:
p-top==MAXNUM-1,栈满时,不能入栈;否则出现空间溢出,引起错误,这种现象称为上溢。
出栈和读栈顶元素操作,先判栈是否为空,为空时不能操作,否则产生错误。
通常栈空作为一种控制转移的条件。
注意:
(1)顺序栈中元素用向量存放
(2)栈底位置是固定不变的,可设置在向量两端的任意一个端点
(3)栈顶位置是随着进栈和退栈操作而变化的,用一个整型量top(通常称top为栈顶指针)来指示当前栈顶位置
参考程序:
#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;
}
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-top0)
printf("这是一个空栈!
");
printf("\n");
for(i=p-ii--)
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",
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
}
[实验2]栈的链式表示和实现
实验内容与要求:
编写一个程序实现链栈的各种基本运算,并在此基础上设计一个主程序,完成如下功能:
(1)初始化链栈
(2)链栈置空
(3)入栈
(4)出栈
(5)取栈顶元素
(6)遍历链栈
分析:
链栈是没有附加头结点的运算受限的单链表。
栈顶指针就是链表的头指针。
注意:
(1)LinkStack结构类型的定义可以方便地在函数体中修改top指针本身
(2)若要记录栈中元素个数,可将元素个数属性放在LinkStack类型中定义。
(3)链栈中的结点是动态分配的,所以可以不考虑上溢。
栈的基本操作,附带源程序
参考程序:
#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-//由于是在栈顶pushLstack,所以要指向栈顶。
s-top=p;//插入
}
/*出栈*/
ElemtypepopLstack(LinkStack*s)
{Elemtypex;
StackNode*p;
p=s-//指向栈顶
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-
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",
printf("依次将%d个数据压入链栈:
\n",n);
for(i=1;ii++)
{scanf("%d",
pushLstack(s,a);
}
Disp(s);
}break;
case3:
{printf("\n出栈操作开始!
\n");
printf("输入将要出栈的数据个数:
m=");
scanf("%d",
for(i=1;ii++)
{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
}
[实验3]队列的顺序表示和实现
实验内容与要求
编写一个程序实现顺序队列的各种基本运算,并在此基础上设计一个主程序,完成如下功能:
(1)初始化队列
(2)建立顺序队列
(3)入队
(4)出队
(5)判断队列是否为空
(6)取队头元素
栈的基本操作,附带源程序
(7)遍历队列
分析:
队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表。
入队时,将新元素插入rear所指的位置,然后将rear加1。
出队时,删去front所指的元素,然后将front加1并返回被删元素。
顺序队列中的溢出现象:
(1)"下溢"现象。
当队列为空时,做出队运算产生的溢出现象。
“下溢”是正常现象,常用作程序控制转移的条件。
(2)"真上溢"现象。
当队列满时,做进栈运算产生空间溢出的现象。
“真上溢”是一种出错状态,应设法避免。
(3)"假上溢"现象。
由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。
当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。
该现象称为"假上溢"现象。
注意:
(1)当头尾指针相等时,队列为空。
(2)在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。
参考程序:
#includestdio.h
#includemalloc.h
#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(sq-rear)
{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",
printf("\n请依次输入入顺序队列的元素值:
\n");
for(i=0;ii++)
{scanf("%d",
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("请输入队的值:
\n");
scanf("%d",
append(head,x);
display(head);
break;
}
case4:
{z=Delete(head);
printf("\n队头元素%d已经出队!
\n",z);
display(head);
break;
}
case5:
{if(Empty(head))
printf("队列空\n");
栈的基本操作,附带源程序
else
printf("队列非空\n");
break;
}
case6:
{y=gethead(head);
printf("队头元素为:
%d\n",y);
break;
}
case7:
{display(head);
break;
}
}
}while(select
}
[实验4[队列的链式表示和实现
实验内容与要求:
编写一个程序实现链队列的各种基本运算,并在此基础上设计一个主程序,完成如下功能:
(1)初始化并建立链队列
(2)入链队列
(3)出链队列
(4)遍历链队列
分析:
队列的链式存储结构简称为链队列。
它是限制仅在表头删除和表尾插入的单链表。
注意:
(1)和链栈类似,无须考虑判队满的运算及上溢。
(2)在出队算法中,一般只需修改队头指针。
但当原队中只有一个结点时,该结点既是队头也是队尾,故删去此结点时亦需修改尾指针,且删去此结点后队列变空。
(3)和单链表类似,为了简化边界条件的处理,在队头结点前可附加一个头结点。
参考程序:
#includestdio.h
#includestdlib.h
#defineElemTypeint
typedefstructQnode
{ElemTypedata;
structQnode*next;
}Qnodetype;
typedefstruct
{Qnodetype*front;
栈的基本操作,附带源程序
Qnodetype*rear;
}Lqueue;
/*入链队列*/
voidLappend(Lqueue*q,intx)
{Qnodetype*s;
s=(Qnodetype*)malloc(sizeof(Qnodetype));
s-data=x;
s-next=NULL;
q-rear-next=s;
q-rear=s;
}
/*初始化并建立链队列*/
voidcreat(Lqueue*q)
{Qnodetype*h;
inti,n,x;
printf("输入将建立链队列元素的个数:
n=");
scanf("%d",
h=(Qnodetype*)malloc(sizeof(Qnodetype));
h-next=NULL;
q-front=h;
q-rear=h;
for(i=1;ii++)
{printf("链队列第%d个元素的值为:
",i);
scanf("%d",
Lappend(q,x);
}
}
/*出链队列*/
ElemTypeLdelete(Lqueue*q)
{Qnodetype*p;
ElemTypex;
if(q-front==q-rear)
{printf("队列为空!
\n");
x=0;
}
else
{p=q-front-next;
q-front-next=p-next;
if(p-next==NULL)
q-rear=q-front;
x=p-data;
free(p);
栈的基本操作,附带源程序
}
return(x);
}
/*遍历链队列*/
voiddisplay(Lqueue*q)
{Qnodetype*p;
p=q-front-next;/*指向第一个数据元素节点*/
printf("\n链队列元素依次为:
");
while(p!
=NULL)
{printf("%d--",p-data);
p=p-next;
}
printf("\n\n遍历链队列结束!
\n");
}
main()
{Lqueue*p;
intx,cord;
printf("\n*****第一次操作请选择初始化并建立链队列!
*****\n");
do
{printf("\n链队列的基本操作\n");
printf("=========================================\n");
printf(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作 实验 报告