数据结构 顺序栈 链栈 循环队列 链队列 hrbedu.docx
- 文档编号:9482372
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:39
- 大小:126.01KB
数据结构 顺序栈 链栈 循环队列 链队列 hrbedu.docx
《数据结构 顺序栈 链栈 循环队列 链队列 hrbedu.docx》由会员分享,可在线阅读,更多相关《数据结构 顺序栈 链栈 循环队列 链队列 hrbedu.docx(39页珍藏版)》请在冰豆网上搜索。
数据结构顺序栈链栈循环队列链队列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;i Push(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;i returnOK; } 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: %c\n",a); returnOK; } 6)读栈顶 调用Gethead函数即可完成功能 7)选择需要的功能 用switch分析得到的m,根据不同的m进入不同的case,调用不同的函数 printf("选择你想要的功能\n"); scanf("%d",&m); getchar(); switch(m) {case1: Clear(h);printf("Empty\n");break; case2: if(Empty(h))printf("Empty\n"); elseprintf("NotEmpty");break; case3: printf("进栈元素是: "); scanf("%c",&x); Push(h,x);break; case4: Pop(h);Gethead(h,a);break; case5: Gethead(h,a);break; } (3)循环队列 系统规定的功能设计的算法有: 置空队、判队空、进队、出队、读队头元素、输出 1)初始化和建立队列 S1: 定义结构体 typedefstruct {int*base; intfront; intrear; }SqQueue; S2: 初始化队列 intInit(SqQueue&Q) { Q.base=(int*)malloc(MAXQSIZE*sizeof(int)); if(! Q.base)return(OVERFLOW); Q.front=Q.rear=0; returnOK; } S3: 建立循环队列 intSet(SqQueue&Q) {inti; Init(Q); charstr[100]; printf("请输入队列: \n"); gets(str); intn=strlen(str); for(i=0;i returnOK; } 2)置空队 编写子函数Clear,使其可以实现置空队功能 intClear(SqQueue&Q) { if(Q.rear==Q.front)returnOK; Q.rear=Q.front; returnOK; } 在主函数里调用Clear子函数,就能达到置空队的功能 3)判队空 S1: 编写判断栈空的子函数Empty,使其实现判队空功能 intEmpty(SqQueue&Q) { if(Q.rear==Q.front)returnOK; elsereturnFALSE; } S2: 在主函数调用时根据队中指针位置判断输出内容 if(Q.front==Q.rear)printf("empty"); elseprintf("notempty"); 4)进队 S1: 从客户端得到所要入队的元素 printf("进队元素是: ");scanf("%c",&x); S2: 编写子函数En,使其可以实现将元素入栈功能 intEn(SqQueue&Q,chare) { if((Q.rear+1)%MAXQSIZE==Q.front)returnERROR; Q.base[Q.rear]=e; Q.rear=(Q.rear+1)%MAXQSIZE; returnOK; } 5)出队 S1: 编写子函数De,删除队头元素 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: %c\n",a); returnOK; } 6)读队头元素 调用Gethead函数即可实现 7)输出队中元素 编写子函数Print,使其可以输出队中每一个元素 intPrint(SqQueueQ) { if(Q.rear==Q.front)returnERROR; inta,b; a=Q.front; b=Q.rear; while(a! =b) { (printf("%c\n",Q.base[a])); a=(a+1)%MAXQSIZE; } returnOK; } 8)选择需要的功能 用switch分析得到的m,根据不同的m进入不同的case,调用不同的函数 printf("选择你需要的功能\n"); printf("1置空队\n2判队空\n3进队\n4出队\n5读队头元素\n6输出循环队列\n"); while (1){printf("选择你想要的功能\n"); scanf("%d",&m); switch(m){ case1: Clear(Q);printf("empty");break; case2: if(Q.front==Q.rear)printf("empty"); elseprintf("notempty"); break; case3: printf("你要入队的元素\n"); getchar(); scanf("%c",&x); En(Q,x); break; case4: if(! Empty(Q)){De(Q,e); Gethead(Q,a); printf("新队列头元素: "); printf("%c",a); } elseprintf("队列已空"); break; case5: Gethead(Q,a); printf("新队列头元素: "); printf("%c",a);break; case6: Print(Q);} } (4)链队列 系统规定的功能设计的算法有: 置空队、判队空、进队、出队、读队头元素 1)初始化和建立队列 S1: 定义结构体 typedefstructQNode {intdata; QNode*next; }QNode,*QPtr; typedefstructQlink { QPtrfront; QPtrrear; }Qlink;//定义单链队列的链式存储结构 S2: 初始化 intInitqueue(Qlink&Q) {Q.front=Q.rear=(QPtr)malloc(sizeof(QNode)); if(! Q.front)exit(OVERFLOW); Q.front->next=NULL; returnOK; }//构造空队列 S3: 建立队列 QlinkSetqueue(Qlink&Q) { inti; Initqueue(Q); QPtrp; printf("请输入你的队列"); charstr[100]; gets(str); intn=strlen(str); for(i=0;i {p=(QPtr)malloc(sizeof(QNode)); p->data=str[i]; p->next=NULL; Q.rear->next=p; Q.rear=p; } returnQ; } 2)置空队 编写子函数Clear,使其可以实现置空队功能 intClear(Qlink&Q) {Q.front=Q.rear; returnOK; } 3)判队空 S1: 编写判断栈空的子函数Empty,使其实现判队空功能 intEmpty(Qlink&Q) { if(Q.front==Q.rear) returnTRUE; else returnFALSE; } S2: 在主函数调用时根据队中指针位置判断输出内容 if(Q.front==Q.rear)printf("empty"); elseprintf("notempty"); 4)进队 S1: 从客户端得到所要入队的元素 printf("入队元素是: ");scanf("%c",&x); S2: 编写子函数En,使其可以实现将元素入栈功能 intEn(Qlink&Q,chare) { QPtrp; p=(QPtr)malloc(sizeof(QNode)); if(! p)exit(OVERFLOW); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; free(p); returnOK; } 5)出队 S1: 编写子函数De,删除队头元素 intDe(Qlink&Q,char&e) { if(Q.front==Q.rear)returnFALSE; QPtrp; p=Q.front->next; Q.front->next=p->next; e=p->data; free(p); returnOK; } S2: 编写子函数Gethead,使其可以得到队头元素,从而得到新的队头元素来确认成功 intGethead(QlinkQ,char&n) { if(Q.front==Q.rear)returnFALSE; n=Q.front->next->data; returnOK; } 6)读队头元素 调用函数Gethead就可以达到功能 7)功能选择 用switch分析得到的m,根据不同的m进入不同的case,调用不同的函数 printf("选择你需要的功能\n"); printf("1置空队\n2判队空\n3进队\n4出队\n5读队头元素\n"); while (1){printf("选择你想要的功能\n"); scanf("%d",&m); switch(m){ case1: Clear(Q);printf("empty");break; case2: if(Q.front==Q.rear)printf("empty"); elseprintf("notempty"); break; case3: printf("你要入队的元素\n"); getchar(); scanf("%c",&x); En(Q,x); break; case4: if(! Empty(Q)){De(Q,e); Gethead(Q,a); printf("新队列头元素: "); printf("%c",a); } elseprintf("队列已空");
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 顺序栈 链栈 循环队列 链队列 hrbedu 顺序 循环 队列
![提示](https://static.bdocx.com/images/bang_tan.gif)