数据结构 顺序栈 链栈 循环队列 链队列 hrbedu汇总.docx
《数据结构 顺序栈 链栈 循环队列 链队列 hrbedu汇总.docx》由会员分享,可在线阅读,更多相关《数据结构 顺序栈 链栈 循环队列 链队列 hrbedu汇总.docx(31页珍藏版)》请在冰豆网上搜索。
![数据结构 顺序栈 链栈 循环队列 链队列 hrbedu汇总.docx](https://file1.bdocx.com/fileroot1/2022-10/11/c017863f-8c95-4259-9da7-8cf064e11090/c017863f-8c95-4259-9da7-8cf064e110901.gif)
数据结构顺序栈链栈循环队列链队列hrbedu汇总
第三章实验报告
实验名称:
数据结构第三章实验
实验类型:
验证性
学号
姓名:
红领巾
1.问题描述
(1)顺序栈
●顺序栈的C语言描述
●基本运算的算法——置空栈、判栈空、进栈、出栈、读栈顶、输出栈、判栈满
(2)链栈
●链栈的C语言描述
●基本运算的算法——置空栈、判栈空、进栈、出栈、读栈顶
(3)循环队列
●循环队列的C语言描述
●基本运算的算法——置空队、判队空、进队、出队、读队头元素、输出循环队列
(4)链队列
●链队列的C语言描述
●基本运算的算法——置空队、判队空、进队、出队、读队头元素
2.数据结构设计
(1)顺序栈
要实现顺序栈操作,我们需要一个栈顶指针一个栈底指针,以及说明当前已经分配的存储空间(即当前可使用的最大容量),因此结构中需要定义这三个部分
typedefstruct{
char*base;
char*top;
intstacksize;
}Sq;
(2)链栈
对于链栈,每一个人节点需要有data域和next域,分别储存数据以及指向下一个节点,下一个节点也应该是拥有这两个域,所以用到嵌套定义来定义节点的数据结构
typedefstructnode
{chardata;
structnode*next;
}node;
(3)循环队列
对于循环队列,需要有头尾指针指向队列头元素和尾元素的下一个位置,所以我们定义front,rear指针,为了说明动态分配的存储空间,我们定义了base,这就是循环队列的存储结构
typedefstruct
{int*base;
intfront;
intrear;
}SqQueue;
(4)链队列
根据要求可知,我们运用单链队列即可实现所需要的功能,对于单链队列,我们需要两个指针作为队头队尾指针从而实现队列的操作,所以定义front,rear。
对于每一个节点都有data和next域来存储数据和指向下一个节点,所以进行这种节点定义。
typedefstructQNode
{intdata;
QNode*next;
}QNode,*QPtr;
typedefstructQlink
{QPtrfront;
QPtrrear;
}Qlink;
3.算法设计
(1)顺序栈
系统规定的功能设计的算法有:
置空栈、判栈空、进栈、出栈、读栈顶、输出栈、判栈满
1)初始化和建立顺序栈
S1:
定义数据结构类型
typedefstruct{
char*base;
char*top;
intstacksize;
}Sq//定义结构体,其中包含栈顶、栈尾指针和存储空间
S2:
初始化这个顺序栈
intInitSq(Sq&S){
S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(Sq));
if(!
S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}//申请存储空间,并且将栈顶栈尾元素指在一个位置,构造空栈
S3:
从键盘输入一串字符,根据这些字符构造顺序栈
Sqcreate(Sq&S){
InitSq(S);
printf("请输入你的栈");
charstr[100];
gets(str);//得到字符
intn=strlen(str);
for(inti=0;iPush(S,str[i]);
}//调用Push函数将每个字符入栈
returnS;
}
2)置空栈
编写子函数Clear,使其可以实现置空栈功能
intClear(Sq&S){
while(S.top!
=S.base){
chare;
Pop(S,e);
}
returnOK;
}
在主函数里调用Clear子函数,就能达到置空栈的功能
3)判栈空
S1:
编写判断栈空的子函数Empty,使其实现判栈空功能
intEmpty(SqS){
if(S.top==S.base)
returnOK;
elsereturnERROR;
}
S2:
在主函数调用时根据子函数返回值判断输出内容
if(Empty(S))printf("Empty\n");
elseprintf("NotEmpty");
4)进栈
S1:
从客户端得到所要入栈的元素
printf("进栈元素是:
");scanf("%c",&x);
S2:
编写子函数Push,使其可以实现将元素入栈功能
intPush(Sq&S,chare){
if(S.top-S.base>=S.stacksize){
S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
if(!
S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;//调整指针
S.stacksize+=STACKINCREMENT;//增大空间
}
*S.top++=e;
returnOK;
}
5)出栈
S1:
编写子函数GetTop,使其可以得到栈顶元素,从而确定要删去的元素是什么,并且返回这个元素
intGetTop(SqS,char&e){
if(S.top==S.base)returnERROR;
e=*(S.top-1);
returne;
}
S2:
编写子函数Pop,删除栈顶元素
intPop(Sq&S,chare){
if(S.top==S.base)returnERROR;
e=*--S.top;
returne;
}
S3:
编写子函数Print,让这个函数可以输出栈里每一个元素来输出出栈后的栈里元素
intPrint(SqS){
char*p,*q;
p=S.top;
q=S.base;
if(p==q)returnERROR;
while(p!
=q)
{
printf("%c\n",*(p-1));
p--;
}
returnOK;
}
6)读栈顶
调用函数GetTop,读到栈顶元素,并且输出这个元素
GetTop(S,a);printf("%c\n",a)
7)输出栈
调用函数Print,输出栈里每一个元素
8)判栈满
S1:
编写函数T,使其可以实现判栈满功能
intT(SqS)
{
if(S.top-S.base>=S.stacksize)
returnOK;
else
returnERROR;}
S2:
根据返回值,确定输出内容
if(T(S))printf("Y\n");
elseprintf("N\n");
9)选择功能
S1:
弹出提示,得到键盘处根据提示所输入的字符
printf("选择你想要的功能\n");
printf("1置空栈\n2判断栈空\n3进栈\n4出栈\n5读栈顶\n6输出栈\n7判栈满\n");
printf("选择你想要的功能\n");
scanf("%d",&m);
S2:
用switch分析得到的m,根据不同的m进入不同的case,调用不同的函数
switch(m)
{
case1:
Clear(S);printf("Empty\n");break;
case2:
if(Empty(S))
printf("Empty\n");
elseprintf("NotEmpty");
break;
case3:
printf("进栈元素是:
");scanf("%c",&x);
Push(S,x);Print(S);break;
case4:
GetTop(S,a);Pop(S,a);Print(S);break;
case5:
GetTop(S,a);printf("%c\n",a);break;
case6:
Print(S);break;
case7:
if(T(S))printf("Y\n");
elseprintf("N\n");break;
}
(2)链栈
系统规定的功能设计的算法有:
置空栈、判栈空、进栈、出栈、读栈顶
1)定义节点,初始化链栈,创建链栈
S1:
定义节点
typedefstructnode
{chardata;
structnode*next;
}node;//节点的定义
S2:
初始化链栈
intInit(node*&h)
{h->next=NULL;
returnOK;
}//建立一个空栈
S3:
编写子函数Set,使其根据键盘端的输入,创建链栈
intSet(node*&h)
{inti;
printf("请输入你的栈");
charstr[100];
gets(str);//得到字符串
intn=strlen(str);
for(i=0;ireturnOK;
}
2)置空栈
编写子函数Clear,使其可以实现置空栈功能
intClear(node*&h)
{h->next=NULL;
returnOK;
}
在主函数里调用Clear子函数,就能达到置空栈的功能
3)判栈空
S1:
编写判断栈空的子函数Empty,使其实现判栈空功能
intEmpty(node*&h)
{if(h->next==NULL)
returnOK;
elsereturnFALSE;
}
S2:
在主函数调用时根据子函数返回值判断输出内容
if(Empty(h))printf("Empty\n");
elseprintf("NotEmpty");break;
if(Empty(S))printf("Empty\n");
elseprintf("NotEmpty");
4)进栈
S1:
从客户端得到所要入栈的元素
printf("进栈元素是:
");scanf("%c",&x);
S2:
编写子函数Push,使其可以实现将元素入栈功能
intPush(node*&h,charx)
{node*s;
s=(node*)malloc(sizeof(node));
s->data=x;
s->next=h;
h=s;
returnOK;
}
5)出栈
S1:
编写子函数Pop,删除栈顶元素
intPop(node*&h)
{charx;
x=h->data;
node*p;
p=(node*)malloc(sizeof(node));
p=h;
h=h->next;
free(p);
returnOK;
}
S2:
编写子函数Gethead,使其可以得到栈顶元素,从而得到新的栈顶元素来确认成功
intGethead(node*&h,chara)
{if(h->next==NULL)returnFALSE;
a=h->data;printf("head:
%