用顺序结构表示栈并实现栈的各种基本操作.docx

上传人:b****8 文档编号:10864302 上传时间:2023-02-23 格式:DOCX 页数:21 大小:20.37KB
下载 相关 举报
用顺序结构表示栈并实现栈的各种基本操作.docx_第1页
第1页 / 共21页
用顺序结构表示栈并实现栈的各种基本操作.docx_第2页
第2页 / 共21页
用顺序结构表示栈并实现栈的各种基本操作.docx_第3页
第3页 / 共21页
用顺序结构表示栈并实现栈的各种基本操作.docx_第4页
第4页 / 共21页
用顺序结构表示栈并实现栈的各种基本操作.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

用顺序结构表示栈并实现栈的各种基本操作.docx

《用顺序结构表示栈并实现栈的各种基本操作.docx》由会员分享,可在线阅读,更多相关《用顺序结构表示栈并实现栈的各种基本操作.docx(21页珍藏版)》请在冰豆网上搜索。

用顺序结构表示栈并实现栈的各种基本操作.docx

用顺序结构表示栈并实现栈的各种基本操作

栈的顺序表示和实现

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(srear)

{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(srear)

{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("请输入队

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1