数据结构实验三栈和队列的应用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第三章栈和队列的应用
【实验目的】
1.熟练掌握栈和队列的结构,以及这两种数据结构的特点;
2.能够在两种存储结构上实现栈的基本运算,特别注意栈满和栈空的判断条件及描述方法;
3.熟练掌握链队列和循环队列的基本运算,并特别注意队列满和队列空的判断条件和描述方法;
第一节知识准备
一、栈:
1. 基本概念
栈是一种限定仅在表的一端进行插入与删除操作的线性表。允许进行插入与删除操作的这一端称为栈顶,而另一端称为栈底,不含元素的空表称为空栈,插入与删除分别称进栈与出栈。
由于插入与删除只能在同一端进行,所以较先进入栈的元素,在进行出栈操作时,要比较后才能出栈。特别是,最先进栈者,最后才能出栈,而最晚进栈者,必最先出栈。因此,栈也称作后进先出
(Last In First Out)的线性表,简称LIFO表。
栈示意图见图3-1
2. 栈的抽象数据类型定义:
ADT Stack{
数据对象:D={ | ∈ElemSet, i=1,2,...,n, n>=0}
数据关系:R1={< , >| , ∈D, i=2,...,n}
基本操作:
InitStack(&S) 构造一个空栈S
StackEmpty(S) 判断栈S是否为空
StackLength(S) 返回栈S的元素个数,即栈的长度
GetTop(S,&e) 取栈S的栈顶元素
Push(&S,e) 将元素e入栈
Pop(&S,&e) 删除S的栈顶元素并用e返回其值(即出栈)
}ADT Stack
3. 栈的表示:
栈有两种存储表示方法:顺序存储结构和链式存储结构。
(1)顺序存储结构:
#define STACK_INIT_SIZE 100; //存储空间初始分配量
#define STACKINCREMENT 10; //存储空间分配增量
typedef struct{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int StackSize; //栈的当前容量
}SqStack;
(2)链式存储结构:
Typedef struct Lnode{
ElemType data;
struct Lnode *next;
}Lnode, *LinkList;
二、队列:
1. 与栈相对应,队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端进行删除元素。允许插入的一端称队尾,允许删除的一端称队头。插入与删除分别称为入队与出队。队列示意图见图3-2:──────────────
出队←a1 a2 …… an-1 ←an进队
──────────────
队头队尾
图3-2 队列
2. 队列的抽象数据类型定义:
ADT Queue{
数据对象:D={ | ∈ElemSet, i=1,2,...,n, n>=0}
数据关系:R1={< , >| , ∈D, i=2,...,n}
基本操作:
InitQueue(&Q) 构造一个空队列Q
QueueEmpty(Q) 判断队列是否为空
QueueLenght(Q) 返回队列Q的元素个数,即队列的长度
GetHead(Q,&e) 取队列Q的队头元素,并用e返回
EnQueue(&Q,e) 将元素e入队列
DeQueue(&Q,&e) 删除非空队列Q的队头元素,并用e返回其值
}ADT Queue
3. 队列的表示:
队列有两种表示方法:链队列、循环队列(顺序队列)。
(1)链队列的表示:
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
(2) 循环队列的表示(见第二节)
第二节循环队列的表示和实现
【问题描述】设计一个抽象数据类型队列的顺序表示和实现的演示程序。【数据描述】
#define MaxQsize 100 //最大队列长度
typedef struct {
QElemType *base;//初始化的动态分配存储空间
int front; //头指针,若队列不空,指向队列头元素
int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置}SqQueue;
【算法描述】
Status InitQueue(SqQueue &Q){
//构造一个空队列Q
Q.base=(QelemType *)malloc(MaxQsize*sizeof(QelemType));
if(!Q.base) exit(OVERFLOW);//存储分配失败
Q.front=Q.rear=0;
return OK;
}
Status QueueEmpty(SqQueue Q){
//若队列Q为空队列,则返回TRUE,否则返回FALSE
if(Q.front﹦﹦Q.rear) return TRUE;
else return FALSE;
}
int QueueLength(SqQueue Q){
//返回Q的元素个数,即为队列的长度
return(Q.rear-Q.front+MaxQsize)% MaxQsize;
}
Status GetHead(SqQueue Q,QelemType &e){
//若队列不为空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
return OK;
}
Status EnQueue(SqQueue &Q,QelemType e){
//插入元素e为Q的新的队尾元素
if((Q.rear+1)%MaxQsize==Q.front) return ERROR;//队列满
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MaxQsize;
return OK;
}
Status DeQueue(SqQueue &Q,QelemType &e){
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR