03 第3章 栈和队列
合集下载
大学数据结构课件--第3章 栈和队列

top top 栈空 F E D C B A
栈满 top-base=stacksize
top
F
E
D C B
top top top top top top base
入栈PUSH(s,x):s[top++]=x; top 出栈 POP(s,x):x=s[--top]; top
base
4
A
3.1 栈
例1:一个栈的输入序列为1,2,3,若在入栈的过程中 允许出栈,则可能得到的出栈序列是什么? 答: 可以通过穷举所有可能性来求解:
3.2 栈的应用举例
二、表达式求值
“算符优先法”
一个表达式由操作数、运算符和界限符组成。 # 例如:3*(7-2*3) (1)要正确求值,首先了解算术四则运算的规则 a.从左算到右 b.先乘除后加减 c.先括号内,后括号外 所以,3*(7-2*3)=3*(7-6)=3*1=3
9
3.2 栈的应用举例
InitStack(S); while (!QueueEmpty(Q))
{DeQueue(Q,d);push(S,d);}
while (!StackEmpty(S)) {pop(S,d);EnQueue(Q,d);} }
第3章 栈和队列
教学要求:
1、掌握栈和队列的定义、特性,并能正确应用它们解决实 际问题;
用一组地址连续的存储单元依次存放从队头到队尾的元素, 设指针front和rear分别指示队头元素和队尾元素的位置。
Q.rear 5 4 Q.rear 3 2 3 2 5 4 Q.rear 3 3 5 4 5 4
F E D C
C B A
Q.front
2 1 0
C B
Q.front 2 1 0
栈满 top-base=stacksize
top
F
E
D C B
top top top top top top base
入栈PUSH(s,x):s[top++]=x; top 出栈 POP(s,x):x=s[--top]; top
base
4
A
3.1 栈
例1:一个栈的输入序列为1,2,3,若在入栈的过程中 允许出栈,则可能得到的出栈序列是什么? 答: 可以通过穷举所有可能性来求解:
3.2 栈的应用举例
二、表达式求值
“算符优先法”
一个表达式由操作数、运算符和界限符组成。 # 例如:3*(7-2*3) (1)要正确求值,首先了解算术四则运算的规则 a.从左算到右 b.先乘除后加减 c.先括号内,后括号外 所以,3*(7-2*3)=3*(7-6)=3*1=3
9
3.2 栈的应用举例
InitStack(S); while (!QueueEmpty(Q))
{DeQueue(Q,d);push(S,d);}
while (!StackEmpty(S)) {pop(S,d);EnQueue(Q,d);} }
第3章 栈和队列
教学要求:
1、掌握栈和队列的定义、特性,并能正确应用它们解决实 际问题;
用一组地址连续的存储单元依次存放从队头到队尾的元素, 设指针front和rear分别指示队头元素和队尾元素的位置。
Q.rear 5 4 Q.rear 3 2 3 2 5 4 Q.rear 3 3 5 4 5 4
F E D C
C B A
Q.front
2 1 0
C B
Q.front 2 1 0
DS_chap03

3.2 栈的表示和实现
C语言中,顺序栈也可以采用 语言中, 语言中
静态分配
typedef struct{ SElemType base[STACK_INIT_SIZE]; //指示栈顶位置 int top; //指示栈顶位置 SqStack; }SqStack;
建议! 建议!
动态分配
typedef struct{ SElemType *base; SElemType *top; // 设两指针便于判断栈是否为空 栈的当前可使用的最大容量. int StackSize; // 栈的当前可使用的最大容量. SqStack; }SqStack;
南昌航空大学软件学院
9
第3章 栈和队列
3.2 栈的表示和实现
顺序栈
利用一组地址连续的存储单元依次存放自栈底 到栈顶的数据元素,同时附设指针top指示栈 到栈顶的数据元素,同时附设指针top指示栈 top 顶元素在顺序栈中的位置。 顶元素在顺序栈中的位置。 栈所需最大空间很难估计,一般来说, 栈所需最大空间很难估计,一般来说,在初始 化设空栈时不应限定栈的最大容量。 化设空栈时不应限定栈的最大容量。设定两个 常量: 常量: 存储空间初始分配量 存储空间初始分配量——MAX_STACK MAX_STACK 初始分配量 存储空间分配增量 分配增量——STACKINCREMENT 存储空间分配增量 STACKINCREMENT
南昌航空大学软件学院 14
第3章 栈和队列
3.2 栈的表示和实现
顺序栈
Pop(&S,&e)
void Pop(SqStack &S, SElemType &e) { if (S.top == -1) exit(“Stack empty”); exit( Stack is empty ); else *e=S.base[S.top--]; *e=S.base[S.top--]; -}
第3章_栈和队列

第三章 栈和队列
(Chapter 3. பைடு நூலகம்tack and Queue)
栈的概念、存储结构及其基本操作
栈的应用举例 队列的概念、存储结构及其基本操作
§3.1 栈
3.1.1 栈的定义及基本运算
• 定义:只能在表尾(栈顶)进行插入和删除操 作进行的线性表。 • 特点: 后进先出(LIFO—Last In First Out )
top 栈顶
an an-1
. . .
a1 ∧
栈底
空栈: top == NULL
16
入栈
LinkStack Push_LS (LinkStack top,datatype x) { StackNode *p ; top p = (StackNode *) malloc (sizeof( StackNode)); p->data = x; top p->next = top; top = p; return top; }
23
2
括号匹配的检验:
问题:两种括号,可以嵌套使用,但不能重叠 解决:使用栈。 {([ ][ ])} 左括号进栈, 右括号就从栈顶出栈一个左括号, 检查是否能够匹配。 算法开始和结束时,栈都应该是空的。
匹配一个字符串中的左、右括号。如
[ a * ( b + c ) + d ]
( 出栈
( )匹配
[ 出栈
3.1.2 栈的存储及运算实现
顺序栈 -- 栈的顺序存储表示 链栈 -- 栈的链式存储表示
4
1 顺序栈
顺序栈类型的定义 – 本质 顺序表的简化,唯一需要确定的是栈顶、栈底。 – 通常 栈底:下标为0的一端 栈顶:由top指示,空栈时top=-1
(Chapter 3. பைடு நூலகம்tack and Queue)
栈的概念、存储结构及其基本操作
栈的应用举例 队列的概念、存储结构及其基本操作
§3.1 栈
3.1.1 栈的定义及基本运算
• 定义:只能在表尾(栈顶)进行插入和删除操 作进行的线性表。 • 特点: 后进先出(LIFO—Last In First Out )
top 栈顶
an an-1
. . .
a1 ∧
栈底
空栈: top == NULL
16
入栈
LinkStack Push_LS (LinkStack top,datatype x) { StackNode *p ; top p = (StackNode *) malloc (sizeof( StackNode)); p->data = x; top p->next = top; top = p; return top; }
23
2
括号匹配的检验:
问题:两种括号,可以嵌套使用,但不能重叠 解决:使用栈。 {([ ][ ])} 左括号进栈, 右括号就从栈顶出栈一个左括号, 检查是否能够匹配。 算法开始和结束时,栈都应该是空的。
匹配一个字符串中的左、右括号。如
[ a * ( b + c ) + d ]
( 出栈
( )匹配
[ 出栈
3.1.2 栈的存储及运算实现
顺序栈 -- 栈的顺序存储表示 链栈 -- 栈的链式存储表示
4
1 顺序栈
顺序栈类型的定义 – 本质 顺序表的简化,唯一需要确定的是栈顶、栈底。 – 通常 栈底:下标为0的一端 栈顶:由top指示,空栈时top=-1
数据结构课件第3篇章栈和队列

循环队列实现原理
01
循环队列定义
将一维数组看作首尾相接的环形结构,通过两个指针(队头和队尾指针)
在数组中循环移动来实现队列的操作。当队尾指针到达数组末端时,再
回到数组起始位置,形成循环。
02
判空与判满条件
在循环队列中,设置一个标志位来区分队列为空还是已满。当队头指针
等于队尾指针时,认为队列为空;当队尾指针加1等于队头指针时,认
栈在函数调用中应用
函数调用栈
在程序执行过程中,每当发生函数调用时,系统会将当前函数的执行上下文压入一个专门的栈中,称为函数调用 栈。该栈用于保存函数的局部变量、返回地址等信息。当函数执行完毕后,系统会从函数调用栈中弹出相应的执 行上下文,并恢复上一个函数的执行状态。
递归调用实现
递归调用是一种特殊的函数调用方式,它通过在函数调用栈中反复压入和弹出同一函数的执行上下文来实现对问 题的分解和求解。在递归调用过程中,系统会根据递归深度动态地分配和管理函数调用栈的空间资源。
栈和队列的应用
栈和队列在计算机科学中有着广泛的应用,如函数调用栈、表达式求 值、缓冲区管理等。
常见误区澄清说明
误区一
栈和队列的混淆。虽然栈和队列都是线性数据结构,但它们的操作方式和应用场景是不同的。栈是后进先出,而队列 是先进先出。
误区二
认为栈和队列只能通过数组实现。实际上,栈和队列可以通过多种数据结构实现,如链表、循环数组等。具体实现方 式取决于应用场景和需求。
后缀表达式求值
利用栈可以方便地实现后缀表达式的求值。具体步骤 为:从左到右扫描表达式,遇到数字则入栈,遇到运 算符则从栈中弹出所需的操作数进行计算,并将结果 入栈,最终栈中剩下的元素即为表达式的结果。
中缀表达式转换为后缀表达式
数据结构第03章栈和队列.ppt

a1 称为 栈底元素 an 称为 栈顶元素
插入元素到栈顶(即表尾)的操作,称为入栈。 从栈顶(即表尾)删除最后一个元素的操作,称为出栈。
强调:插入和删除都只能在表的一端(栈顶)进行!
6
栈的抽象数据类型
ADT Stack{ 数 据 对 象 : D={ai | ai ElemSet , i=1 , 2,... ,n,n>=0} 数据关系: R={<ai-1 , ai >| ai-1 , ai D , i=2,...,n} 基本操作: 栈初始化:StackInit() 判栈空:StackEmpty(S) 入栈:Push(S,x) 出栈:Pop(S)
较好的做法是,设立一个输入缓冲区,用以 接受用户输入的一行字符,然后逐行存入用户数 据区。允许用户输入出错,并在发现有误时可以 及时更正。
29
可以把输入缓冲区设为一个栈结构,每当 从终端接受了一个字符后先作如下判别:如果 它既不是退格符也不是退行符,则将该字符压 入栈顶;如果是一个退格符,则从栈顶删去一 个字符;如果是一个退行符,则将字符栈清空 为空栈。
19
顺序栈基本操作--初始化
SqStack InitStack(SqStack &S) {//构造一个空栈S S.base=(SElemtype *)malloc (STACK_INIT_SIZE)*sizeof(SElemtype); if(!S.base) exit(OVERFLOW); S.top=s.base; S.stackzise=STACK_INIT_SIZE; return OK; }
] 6
) 7
] 8
可能出现的不匹配的情况: 1.到来的右括弧不是所“期待”的; 2.到来的是“不速之客”(左括号); 3.直到结束,也没有到来所“期待”的;
插入元素到栈顶(即表尾)的操作,称为入栈。 从栈顶(即表尾)删除最后一个元素的操作,称为出栈。
强调:插入和删除都只能在表的一端(栈顶)进行!
6
栈的抽象数据类型
ADT Stack{ 数 据 对 象 : D={ai | ai ElemSet , i=1 , 2,... ,n,n>=0} 数据关系: R={<ai-1 , ai >| ai-1 , ai D , i=2,...,n} 基本操作: 栈初始化:StackInit() 判栈空:StackEmpty(S) 入栈:Push(S,x) 出栈:Pop(S)
较好的做法是,设立一个输入缓冲区,用以 接受用户输入的一行字符,然后逐行存入用户数 据区。允许用户输入出错,并在发现有误时可以 及时更正。
29
可以把输入缓冲区设为一个栈结构,每当 从终端接受了一个字符后先作如下判别:如果 它既不是退格符也不是退行符,则将该字符压 入栈顶;如果是一个退格符,则从栈顶删去一 个字符;如果是一个退行符,则将字符栈清空 为空栈。
19
顺序栈基本操作--初始化
SqStack InitStack(SqStack &S) {//构造一个空栈S S.base=(SElemtype *)malloc (STACK_INIT_SIZE)*sizeof(SElemtype); if(!S.base) exit(OVERFLOW); S.top=s.base; S.stackzise=STACK_INIT_SIZE; return OK; }
] 6
) 7
] 8
可能出现的不匹配的情况: 1.到来的右括弧不是所“期待”的; 2.到来的是“不速之客”(左括号); 3.直到结束,也没有到来所“期待”的;
第三章栈和队列

◆ 结点出栈:首先执行top减1,使top指向栈顶元 素的存储位置,然后将栈顶元素取出。
top top bottom
top
空栈 bottom 元素a进栈 top
a
bottom 元素b,c进栈
f e d b a
c b a
top bottom 元素c退栈
b a
bottom 元素d,e,f进栈
图3-2 (动态)堆栈变化示意图
循环队列的基本操作
1 循环队列的初始化
void Init_CirQueue (SqQueue *q)
{
q->front=q->rear=0;
}
2 入队操作
Status Insert_CirQueue(SqQueue *q , ElemType e)
/* 将数据元素e插入到循环队列Q的队尾 */
{ if ((q->rear+1)%MaxSize== q->front)
对于队列,和顺序栈相类似,也有动态和静态之分。 本部分介绍的是静态顺序队列,其类型定义如下:
#define MAX_QUEUE_SIZE 100
typedef struct queue { ElemType Queue_array[MAX_QUEUE_SIZE] ; int front ; int rearue{ 数据对象:D ={ ai|ai∈ElemSet, i=1, 2, …, n, n >= 0 }
数据关系:R = {<ai-1, ai> | ai-1, ai∈D, i=2,3,…,n } 约定a1端为队首,an端为队尾。 基本操作:
Create():创建一个空队列;
return ERROR;
第3章 栈和队列
{ x=N%2; Push(&S, x); N=N/2; }
while(!IsEmpty(S)) { Pop(&S,&x); printf(“%d”,x); } }
返回主目录
2. 括号匹配问题
思想:在检验算法中设置一个栈,若读入的是左括号, 则直接入栈,等待相匹配的同类右括号;若读入的是 右括号,且与当前栈顶的左括号同类型,则二者匹配, 将栈顶的左括号出栈,否则属于不合法的情况。另外, 如果输入序列已读尽,而栈中仍有等待匹配的左括号, 或者读入了一个右括号,而栈中已无等待匹配的左括 号,均属不合法的情况。当输入序列和栈同时变为空 时,说明所有括号完全匹配。
注意:链栈在使用完毕时,应该释放其空间。
返回主目录
用C语言定义的链栈结构
typedef struct node
{
StackElementType data;
struct node *next;
}LinkStackNode;
typedef LinkStackNode *LinkStack;
返回主目录
进OVS
读字符W Y N W是操作符 Y OPTR栈空 N W优先级≤OPTR栈 顶优先级 Y 结束 进OPTR栈 W=„#‟‟ Y
N
N Y
退OVS顶、次顶,OPTR顶 将T(i)=>OVS新顶
返回主目录
2) 算术表达式处理规则 (1) 规定优先级表;
(2) 设置两个栈:OVS(运算数栈)和OPTR(运算符 栈);
返回主目录
算法:
void BracketMatch(char *str) {Stack S; int i; char ch; InitStack(&S); For(i=0; str[i]!='\0'; i++) {switch(str[i]) {case '(': case '[': case '{': Push(&S,str[i]); break; {GetTop (&S,&ch); if(Match(ch,str[i])) Pop(&S,&ch); else { printf("\n对应的左右括号不同类!"); return;} } }/*switch*/ }/*for*/ if(IsEmpty(S)) printf("\n括号匹配!"); else printf("\n左括号多余!"); }
第3章 限定性线性表——栈和队列
两栈共享技术(双端栈):
主要利用了栈“栈底位置不变,而栈顶位置动态变
化”的特性。首先为两个栈申请一个共享的一维数 组空间S[M],将两个栈的栈底分别放在一维数组的 两端,分别是0,M-1。
共享栈的空间示意为:top[0]和top[1]分别为两个 栈顶指示器 。
Stack:0
M-1
top[0]
top[1]
(1)第i号栈的进栈操作 int pushi(LinkStack top[M], int i, StackElementType x) { /*将元素x进入第i号链栈*/
LinkStackNode *temp; temp=(LinkStackNode * )malloc(sizeof(LinkStackNode)); if(temp==NULL) return(FALSE); /* 申请空间失败 */ temp->data=x; temp->next=top[i]->next; top[i]->next=temp; /* 修改当前栈顶指针 */ return(TRUE); }
case 1:if(S->top[1]==M) return(FALSE);
*x=S->Stack[S->top[1]];S->top[1]++;break;
default: return(FALSE);
}
return(TRUE);
返回主目录
}
【思考题】
说明读栈顶与退栈顶的处理异同,并标明将已知 的退栈顶算法改为读栈顶算法时应做哪些改动。
返回主目录
链栈的进栈操作
int Push(LinkStack top, StackElementType x)
第3章栈和队列
第3章栈和队列
3.1.2 栈的表示和算法实现
1.顺序栈 2.链栈
第3章栈和队列
1. 顺序栈 顺序栈是用顺序存储结构实现的栈,即利 用一组地址连续的存储单元依次存放自栈 底到栈顶的数据元素,同时由于栈的操作 的特殊性,还必须附设一个位置指针top( 栈顶指针)来动态地指示栈顶元素在顺序 栈中的位置。通常以top=-1表示空栈。
第 3 章 栈和队列
3.1 栈 3.2 队列 3.3 栈和队列的应用
第3章栈和队列
3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和算法实现
第3章栈和队列
3.1.1 栈的定义
1.栈的定义 栈(stack)是一种只允许在一端进行插入和删除的线 性表,它是一种操作受限的线性表。在表中只允许进
行插入和删除的一端称为栈顶(top),另一端称为 栈 底 (bottom) 。 栈 的 插 入 操 作 通 常 称 为 入 栈 或 进 栈 (push),而栈的删除操作则称为出栈或退栈(pop)。 当栈中无数据元素时,称为空栈。
栈是按照后进先出 (LIFO)的原则组 织数据的,因此, 栈也被称为“后进 先出”的线性表。
第3章栈和队列
(2)入栈操作
Status Push(SqStack &S, Elemtype e)
【算法3.2 栈的入栈操作】
{ /*将元素e插入到栈S中,作为S的新栈顶*/
if (S->top>= Stack_Size -1) return ERROR;
else { S->top++;
S->elem[S->top]=e;
return OK;}
Push(S,’you’)
3.1.2 栈的表示和算法实现
1.顺序栈 2.链栈
第3章栈和队列
1. 顺序栈 顺序栈是用顺序存储结构实现的栈,即利 用一组地址连续的存储单元依次存放自栈 底到栈顶的数据元素,同时由于栈的操作 的特殊性,还必须附设一个位置指针top( 栈顶指针)来动态地指示栈顶元素在顺序 栈中的位置。通常以top=-1表示空栈。
第 3 章 栈和队列
3.1 栈 3.2 队列 3.3 栈和队列的应用
第3章栈和队列
3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和算法实现
第3章栈和队列
3.1.1 栈的定义
1.栈的定义 栈(stack)是一种只允许在一端进行插入和删除的线 性表,它是一种操作受限的线性表。在表中只允许进
行插入和删除的一端称为栈顶(top),另一端称为 栈 底 (bottom) 。 栈 的 插 入 操 作 通 常 称 为 入 栈 或 进 栈 (push),而栈的删除操作则称为出栈或退栈(pop)。 当栈中无数据元素时,称为空栈。
栈是按照后进先出 (LIFO)的原则组 织数据的,因此, 栈也被称为“后进 先出”的线性表。
第3章栈和队列
(2)入栈操作
Status Push(SqStack &S, Elemtype e)
【算法3.2 栈的入栈操作】
{ /*将元素e插入到栈S中,作为S的新栈顶*/
if (S->top>= Stack_Size -1) return ERROR;
else { S->top++;
S->elem[S->top]=e;
return OK;}
Push(S,’you’)
数据结构与算法C版课件第三章栈和队列
x成为新的栈顶元素。 (4)出栈pop(s):删除栈s的栈顶元素。 (5)读栈顶元素top(s):栈顶元素作为结果返回,
不改变栈的状态。
4.栈的存储 (1)采用顺序方式存储的栈称为顺序栈(sequential stack) (2) 采用链接方式存储的栈称为链栈(linked stack)
3.1.2 顺序栈及运算的算法实现
用栈来实现括号匹配检查的原则是,对表达式从左到右扫描。 (1)当遇到左括号时,左括号入栈; (2)当遇到右括号时,首先检查栈是否空,若栈空,则表明该“右括弧”多余;否则比 较栈顶左括号是否与当前右括号匹配,若匹配,将栈顶左括号出栈,继续操作;否则,表明 不匹配,停止操作。 (3)当表达式全部扫描完毕,若栈为空,说明括号匹配,否则表明“左括弧”有多余的。
出队
a1 a2 a3 a4 a5
入队
队列图示
4.队列的应用
5. 在队列上进行的基本运算
(1)队列初始化initQueue(q):构造一个空队列。 (2)判队空emptyQueue(q):若q为空队则返回为1,否
则返回为0。
(3)入队enQueue(q,x):对已存在的队列q,插入一个元素x
到队尾,队发生变化。
队列中元素个数的计算公式。
(4)出队deQueue(q,x):删除队头元素,并通过x返回其值,
队发生变化。
(5)读队头元素frontQueue(q):读队头元素,并返回其值,
队不变。
3.2.2 顺序队列及运算的实现
采用顺序方法存储的队列称为顺序队列(sequential queue)
顺序队列的存储结构用c语言定义如下:
#define MAXSIZE 1024
运算受限的线性 表
表两端插删
不改变栈的状态。
4.栈的存储 (1)采用顺序方式存储的栈称为顺序栈(sequential stack) (2) 采用链接方式存储的栈称为链栈(linked stack)
3.1.2 顺序栈及运算的算法实现
用栈来实现括号匹配检查的原则是,对表达式从左到右扫描。 (1)当遇到左括号时,左括号入栈; (2)当遇到右括号时,首先检查栈是否空,若栈空,则表明该“右括弧”多余;否则比 较栈顶左括号是否与当前右括号匹配,若匹配,将栈顶左括号出栈,继续操作;否则,表明 不匹配,停止操作。 (3)当表达式全部扫描完毕,若栈为空,说明括号匹配,否则表明“左括弧”有多余的。
出队
a1 a2 a3 a4 a5
入队
队列图示
4.队列的应用
5. 在队列上进行的基本运算
(1)队列初始化initQueue(q):构造一个空队列。 (2)判队空emptyQueue(q):若q为空队则返回为1,否
则返回为0。
(3)入队enQueue(q,x):对已存在的队列q,插入一个元素x
到队尾,队发生变化。
队列中元素个数的计算公式。
(4)出队deQueue(q,x):删除队头元素,并通过x返回其值,
队发生变化。
(5)读队头元素frontQueue(q):读队头元素,并返回其值,
队不变。
3.2.2 顺序队列及运算的实现
采用顺序方法存储的队列称为顺序队列(sequential queue)
顺序队列的存储结构用c语言定义如下:
#define MAXSIZE 1024
运算受限的线性 表
表两端插删
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
-退栈输出,退栈 到(止
/ 进栈 ( 进栈 输出7 - 进栈 输出4 -退栈输出,退栈 到(止
19
20
*
1 2 + 8 2 - 7 4 - /
}
2013年8月8日星期四 18
3.1.5
链栈
1、链栈结构及数据类型
栈的链式存贮结构,也称为链栈,它是一种限制运算的链 表,即规定链表中的扦入和删除运算只能在链表开头进行。 链栈结构见图3-5。 以下的输入序列为an,an-1,…a1
top
头
a1
a2
……
an ^
栈顶 图 3-5 链栈结构示意图
2013年8月8日星期四
2013年8月8日星期四
13
(5)判栈空否
int empty(seqstack s)
{
if (s.top= =0) return 1; else return 0;
}
2013年8月8日星期四 14
3、栈的共享存储单元
有时,一个程序设计中,需要使用多个同一类型的栈, 这时候,可能会产生一个栈空间过小,容量发生溢出,而 另一个栈空间过大,造成大量存储单元浪费的现象。 为了 充分利用各个栈的存储空间,这时可以采用多个栈共享存 储单元,即给多个栈分配一个足够大的存储空间,让多个 栈实现存储空间优势互补。
2013年8月8日星期四
22
(3)退栈运算
void pop(link *top) { link *s; s=top->next; if(s!=NULL) { top->next=s->next; delete(s); }}
2013年8月8日星期四 23
(4)取栈顶元素 elemtype gettop(link *top) { if(top->next!=NULL) return(top->next->data); else return(NULL);
详细的示意图 见书P59的图3.1
退出
进入
栈 讨论输入序列为1 2 3的有关 顶
an
情况: 反序: 正序:其他
栈 底
2013年8月8日星期四
a1
5
课堂作业: 1.把输入序列 1 2 3 经过栈的操作可能的所 有结果进行讨论
注意逻辑思维的规律思想方法
2013年8月8日星期四
6
3.1.2
栈的运算
1、初始化栈:INISTACK(&S)
2013年8月8日星期四 7
3.1.3 栈的抽象数据类型描述
ADT Stack is Data: 含有n个元素a1,a2,a3,…,an,按LIFO规则存放,每个元素的类型都为elemtype。 Operation: Void inistack(&s) Void Push(&s,x) “压入” Void Pop(&s) “弹出” //将栈S臵为一个空栈(不含任何元素) //将元素X插入到栈S中,也称为 “入栈”、 “插入”、 //删除栈S中的栈顶元素,也称为”退栈”、 “删除”、
栈底
19
课堂作业: 1. 编写链栈的进栈和出栈操作的算法
2013年8月8日星期四
20
2、链栈的五种栈运算
(1)栈初始化 void inistack(link *top) { top->next=NULL;}
2013年8月8日星期四
21
(2)进栈运算 void push(link *top,int x) { link *s; s=new link; s->data=x; s->next=top->next; top->next=s; }
else if (k==0) { s.top[0]++;s.stack[s.top[0]]=x;} else {s.top[1]--; s.stack[s.top[1]]=x;} }
2013年8月8日星期四 17
(2)两个栈共享存储单元的退栈算法
void pop(duseqstack &s, int k)
栈1底 栈1顶 图 3-3 两个栈共享存储单元示意图
2013年8月8日星期四 15
栈2底 栈2顶
两个栈共享存储单元可用如下C++语句描述:
CONST int maxsize=maxlen;
//maxlen为共享单元的最大长度
Struct
duseqstack
stack[maxsize];
{ elemtype int ……… };
if (s.top= =0) cout<<”underflow”;
else
s.top--;
}
2013年8月8日星期四 12
(4)取栈顶元素
elemtype gettop(seqstack s)
{
if (s.top= =0) {cout<<”underflow”;return 0;} else return s.stack[s.top]; }
2013年8月8日星期四 10
(2)进栈 void push(seqstack &s, elemtype x) {
if (s.top==maxsize-1} cout<<”overflow”;
else
{
s.stack[s.top]=x;
s.top++;
}
}
2013年8月8日星期四 11
(3)退栈 void pop(seqstack &s) {
将中缀表达式(1+2)*((8-2)/(7-4))变成等价的后缀表达式。
现在用栈来实现该运算,栈的变化及输出结果如下
2013年8月8日星期四
31
步骤
1
2 3 4 5 6 7 8 9 10
栈中元 素 ( ( (+ (+ 1 1 1 2
输出结果
说明
(进栈
输出1 +进栈 输出2 +退栈输出,退栈 到(止 *进栈 (进栈 (进栈 输出8 - 进栈
Struct seqstack
{ elemtype elemtype类型 stack[maxsize]; //将栈中元素定义为
int top;
}
//:指向栈顶位臵的指针
2013年8月8日星期四
9
2、栈的五种运算
(1)初始化栈
void inistack(seqstack &s)
{ s.top=0;
}
2013年8月8日星期四
3
根据栈的定义可知,最先放入栈中元素在栈 底,最后放入的元素在栈顶,而删除元素刚好相 反,最后放入的元素最先删除,最先放入的元素 最后删除。
也就是说,栈是一种后进先出(Last First Out)的线性表,简称为LIFO表。
In
没有元素时称为空栈
2013年8月8日星期四
4
7
1+6进入操作数栈
28
2013年8月8日星期四
步骤 10 11 12 13 14 15 16 17
操作数栈 7 7 4 7 4 7 4 2 7 7 2
运算符栈 - / - / -
说明 -进入运算符栈 4进入操作数栈 /进入运算符栈 2进入操作数栈 退栈 4/2进入操作数栈 退栈
5
7-2进入操作数栈
}
2013年8月8日星期四 24
(5)判栈空
int empty(link *top)
{
if(top->next==NULL)
return(1);
else return(0); }
2013年8月8日星期四 25
3.1.6
栈的应用
栈在日常生活中和计算机程序设计中有着许多 应用,下面仅介绍栈在计算机中的应用。
29
2013年8月8日星期四
以下内容目前不做要求 当然,算术表达式除了简单求值外,还会涉及到算术表达式的两 种表示方法,即中缀表示法和后缀表示法。刚才的例3-3中的表达式就 是中缀表达式,中缀表达式求值较麻烦(须考虑运算符的优先级,甚 至还要考虑圆括号),而后缀表达式求值较方便(无须考虑运算符的 优先级及圆括号)。下面将介绍算术表达式的中缀表示和后缀表示及 它们的求值规律,
例如,对于下列各中缀表达式: (1)3/5+8 (2)18-9*(4+3) (3)(25+x)*(a*(a+b)+b) 对应的后缀表达式为: (1)3 5 / 8 + (2)18 9 4 3 + * (3)25 x + a a b + * b + *
2013年8月8日星期四 30
2、中缀表达式变成等价的后缀表达式
第3章
栈和队列
2013年8月8日星期四
1
主要内容
栈
队列
这两种结构都是特殊的线性表
2013年8月8日星期四
2
3.1
栈
3.1.1 栈的定义
栈(stack)是限制线性表中元素的插入和删除 只能在线性表的同一端进行的一种特殊线性表。
允许插入和删除的一端,为变化的一端,称为 栈 顶 (Top) , 另 一 端 为 固 定 的 一 端 , 称 为 栈 底 (Bottom)。
2013年8月8日星期四
top[2] ; //两个栈的栈顶指针
16
(1)两个栈共享存储单元的进栈算法
void dupush(duseqstack &s, elemtype x, int k) //将元素x进入到以S为栈空间的第k个栈中 { if (s.top[0]+1==s.top[1]) cout<<“overflow”
将栈S臵为一个空栈(不含任何元素)。