3栈和队列.ppt

Download Report

Transcript 3栈和队列.ppt

第3章 栈和队列
栈和队列是两种重要的线性结构。
栈和队列是操作受限的线性表。
本章讨论栈和队列的定义、表示方法和实
现外,还将给出一些应用的例子。
第3章 栈和队列
3.1
3.2
3.3
3.4
栈
栈的应用举例
队列
队列的应用举例
3.1
栈 (Stack)
3.1.1 栈的定义
只允许在一端插入和删除
的顺序表

允许插入和删除的一端称
为栈顶 (top),另一端称为
栈底(bottom)


特点: 后进先出 (LIFO)
栈的基本操作
栈的抽象数据类型的定义:
ADT Stack{
数据对象:D={ ai | ai∈Elemset , i =1,2,…,n, n>=0}
数据关系:R1={< ai-1, ai > | ai-1,ai ∈ D, i = 1,2,…,n}
约定an端为栈顶, a1端为栈底。
基本操作:
InitStack(&S) 操作结果:构造一个空栈s。
DestroyStack(&S) 初始条件:栈s已存在。作结果:栈s被销毁。
ClearStack(&S) 初始条件:栈s已存在。操作结果:将s清为空栈。
StackEmpty(S) 初始条件:栈s已存在。操作结果:若栈S为空栈,则
返回TRUE,否则FALSE。
3.1.2
1. 顺序栈
2. 链栈
栈的表示和实现
1. 顺序栈
顺序栈:利用数组存放自栈底到栈顶的数据元素,附
设指针top指示栈顶元素在顺序栈中的位置。
#define MAXSIZE 1024
Typedef struct {
DataType data[MAXSIZE];
int top;
}SeqStack;
栈底初值 top=0
空栈
top=-1
栈满
top=MAXSIZE-1
进栈示例
退栈示例
顺序栈的操作
栈的初始化
SeqStack *Init_SeqStack() {
SeqStack *s;
s=new SeqStack;
if(!s)
{ cout<<“空间不足”<<endl;
return NULL;
}
else
{ s->top=-1;
return s;
}
}
栈空判别
int Empty_SeqStack(SeqStack *s) {
if (s->top==-1)
return 1;
else
return 0;
}
元素进栈
int Push_SeqStack(SeqStack *s,
DataType x) {
if (s->top==MAXSIZE-1)
return 0;
else
{ s->top++;
s->data[s->top]=x;
return 1;
}
}
元素出栈
int Pop_SeqStack(SeqStack *s,
DataType *x) {
if (Empty_SeqStack(s))
return 0;
else
{ *x=s->data[s->top];
s->top--;
return 1;
}
}
问题
能否两个栈共享一个数组空间?
取栈顶元素
DataType Top_SeqStack(SeqStack *s) {
if (Empty_SeqStack(s))
return 0;
else
return s->data[s->top];
}
2. 链栈
链栈:栈的链式表示。
data
next
top
栈顶
Typedef struct Node{
DataType data;
struct Node *next;
}StackNode,*LinkStack;
链栈示意图
栈底 LinkStack top;
链栈的初始化
LinkStack Init_LinkStack() {
return NULL;
}
链栈空判别
int Empty_LinkStack(LinkStack top) {
if (top==NULL)
return 1;
else
return 0;
}
元素进链栈
LinkStack Push_LinkStack(LinkStack
*s,DataType x) {
s=new StackNode; top
s->data=x;
s
x
s->next=top;
top
top=s;
s
x
return top;
top
}
s
x
top
s
x
元素出链栈
LinkStack Pop_LinkStack(LinkStack
*s,DataType *x) {
x 98
if (top==NULL)
p
data next
return NULL;
top
98
else
{ *x=top->data;
top
93
p=top;
top=top->next;
delete p;
return top;
86
}
}
3.2 栈的应用举例
栈具有后进先出的特性,成为程序设
计中的有用工具。

记数进制转换

迷宫求解

表达式求值
【例3-1】数制转换
十进制数N和d进制数的转换原理:
N=(N div d)*d + N mod d,
div为整除运算,mod为求余运算
例如:(1348)10=(2504)8,运算过程:
N
1348
168
21
2
N div 8
168
21
2
0
N mod 8
4
0
5
2
将计算过程中
得到的各位余数顺
序进栈,按出栈序
列打印输出的即为
对应的八进制数。
数制转换算法
void conversion ( ) {
//对于输入的十进制整数,打印输出与其等值的八进制数
InitStack(S); //构造空栈
scanf (”%d”,N);
while(N){
Push(S,N%8);
N = N/8; }
while (!StackEmpty(s)) {
Pop(S, e);
printf(“%”,e); }
} //Conversion
入
【例3-2】迷宫求解
口
求迷宫中从入口到出口
的所有路径是一个经典的程
序设计问题。
迷宫
“穷举求解”法:从入口出发,顺某一方向向前,能
走通则往前走;否则沿原路退回,换一个方向探索,
直至所有可能的通路都探索到为止。
为了保证能沿原路退回,需要用一个后进先出的结
构来保存从入口到当前位置的路径。——“栈” 。
出
口