第3章_2 栈和队列

合集下载

数据结构-Java语言描述 第三章 栈和队列

数据结构-Java语言描述 第三章 栈和队列

System.exit(1);
}
栈顶指针top的初始值决
top=-1;
定了后续其他方法的实现
stackArray=(T[])new Object[n];
}
【算法3-2】入栈
public void push(T obj)
{
if(top==stackArray.length-1){
T []p=(T[])new Object [top*2];
(b)元素a2入栈
an … … a2 a1
(c)元素an入栈
an-1 … a2 a1
(d)元素an出栈
a2 a1
(e)元素a3出栈
a1
(f)元素a2出栈
【例3-1】一个栈的输入序列是1、2、3、4、5,若在 入栈的过程中允许出栈,则栈的输出序列4、3、5、1、 2可能实现吗?1、2、3、4、5的输出呢?
型 正序遍历:依次访问栈中每个元素并输出
3.1.2 顺序栈
顺序栈泛型类的定义如下:
public class sequenceStack<T> {
顺序栈中一维数组 的初始长度
final int MaxSize=10;
private T[] stackArray; 存储元素的数组对象
private int top;
public void nextOrder() {
for(int i=top;i>=0;i--) System.out.println(stackArray[i]);
}
【算法3-8】清空栈操作
public void clear() {
top=-1; }
3.1.3 链栈
栈的链接存储结构称为链栈。结点类的定义,同 第二章Node类。

数据结构(C语言)第3章 栈和队列

数据结构(C语言)第3章 栈和队列

Data Structure
2013-8-6
Page 13
栈的顺序存储(顺序栈)
利用一组地址连续的存储单元依次存放自栈底到栈顶的数 据元素。 结构定义: #define STACK_INIT_SIZE 100; // 存储空间初始分配量 #define STACKINCREMENT 10; // 存储空间分配增量 typedef struct { SElemType *base; // 存储空间基址 SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素位单位 } SqStack;
解决方案2:
顺序栈单向延伸——使用一个数组来存储两个栈
Data Structure 2013-8-6 Page 21
两栈共享空间 两栈共享空间:使用一个数组来存储两个栈,让一个 栈的栈底为该数组的始端,另一个栈的栈底为该数组 的末端,两个栈从各自的端点向中间延伸。
Data Structure
2013-8-6
链栈需要加头结点吗? 链栈不需要附设头结点。
Data Structure
2013-8-6
Page 27
栈的链接存储结构及实现
Data Structure
2013-8-6
Page 11
GetTop(S, &e) 初始条件:栈 S 已存在且非空。 操作结果:用 e 返回S的栈顶元素。 Push(&S, e) 初始条件:栈 S 已存在。 操作结果:插入元素 e 为新的栈顶元素。 Pop(&S, &e) 初始条件:栈 S 已存在且非空。 操作结果:删除 S 的栈顶元素,并用 e 返回其值。
Data Structure

大学数据结构课件--第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

第3章栈和队列-数据结构与算法(第2版)-汪沁-清华大学出版社

第3章栈和队列-数据结构与算法(第2版)-汪沁-清华大学出版社

an
队头
队尾
队列示意图
入队
13
2、队列的基本运算
初始化队列 INIQUEUE(&Q)
将队列Q设置成一个空队列。
入队列
ENQUEUE(&Q,X)
将元素X插入到队尾中,也称“进队” ,“插入”。
出队列
DLQUEUE(&Q)
将队列Q的队头元素删除,也称“退队”、“删除”。
取队头元素 GETHEAD(Q)
也就是说,栈是一种后进先出(Last In First Out)的线性表,简称为LIFO表。
3
2、栈的运算
初始化栈:INISTACK(&S)
将栈S置为一个空栈(不含任何元素)。
进栈:PUSH(&S,X)
将元素X插入到栈S中,也称为 “入栈”、 “插入”、 “压 入”。
出栈: POP(&S)
删除栈S中的栈顶元素,也称为”退栈”、 “删除”、 “弹 出”。
9
三、链栈
typedef struct Lsnode { ElemType data;
struct Lsnode *next; } Lsnode *top;
一个链表栈由ቤተ መጻሕፍቲ ባይዱ顶指针top唯一确定。
10
1、链栈的主要运算
进栈操作 void Push(Lsnode *top; ElemType x)
{ p=(Lsnode *)malloc(sizeof(Lsnode)); p->data=x; p->next=top->next; top->next=p; }/*Push*/
第3章 栈和队列
1
栈和队列是二种特殊的线性表。是操作受 限的线 性表。 一、栈

数据结构栈和队列ppt课件

数据结构栈和队列ppt课件

栈的运用 例3.1 将一个十进制正整数N转换成r进制的数
N 〕
1835
229
28
3
N / 8 〔整除〕 N % 8〔求余
229
3

28
5
3
4
0
3

❖例3.2 算术表达式中括号匹配的检查
❖用栈来实现括号匹配检查的原那么是,对表达式从左 到右扫描。
❖〔1〕当遇到左括号时,左括号入栈;
❖〔2〕当遇到右括号时,首先检查栈能否空,假设栈 空,那么阐明该“右括弧〞多余;否那么比较栈顶左 括号能否与当前右括号匹配,假设匹配,将栈顶左括 号出栈,继续操作;否那么,阐明不匹配,停顿操作 。
❖在顺序栈上实现五种根本运算的C函数 ❖〔3〕入栈 ❖int push (SeqStack *s, DataType x) ❖{ if (s->top==MAXSIZE-1) /*栈满不能入栈*/ ❖{ printf("overflow"); ❖return 0; ❖} ❖ s->top++; ❖ s->data[s->top]=x; ❖ return 1; ❖}
链队列及运算的实现
采用链接方法存储的队列称为链队列〔Linked Queue〕
采用带头结点的单链表来实现链队列,链队列中 的t结ype点de类f st型ruc与t N单od链e 表一样。将头指针front和尾指针 re{arD封at装aTy在pe一da个ta;构造体中,链队列用C言语描画如 下:struct Node *next;
❖只设了一个尾指针r ❖头结点的指针,即r->next ❖队头元素的指针为r->next->next ❖队空的断定条件是r->next==r

数据结构第三章 栈和队列part2)

数据结构第三章 栈和队列part2)
制转移到调用函数。
多个函数嵌套调用的规则是:
后调用先返回 !
此时的内存管理实行“栈式管理”
例如:
void main( ){ void a( ){


a( );
b( );


}//main
}// a
void b( ){
… 函数b的数据区 函数a的数据区 Main的数据区
}// b
递归函数执行的过程可视为同一 函数进行嵌套调用.
例七、实现递归
当在一个函数的运行期间调用另一个函 数时,在运行该被调用函数之前, 需先完成三项任务:
• 将所有的实在参数、返回地址等信息传 递给被调用函数保存;
• 为被调用函数的局部变量分配存储区; • 将控制转移到被调用函数的入口。
从被调用函数返回调用函数之前,应该 完成下列三项任务:
• 保存被调函数的计算结果; • 释放被调函数的数据区; • 依照被调函数保存的返回地址将控
从原表达式求得后缀式的规律为:
1) 设立操作数栈; 2) 设表达式的结束符为“#”,
预设运算符栈的栈底为“#”;
3) 若当前字符是操作数, 则直接发送给后缀式。
从原表达式求得后缀式的规律为:
4) 若当前运算符的优先数高于栈顶运算 符,则进栈;
5) 否则,退出栈顶运算符发送给后缀式;
6) “(” 对它之前后的运算符起隔离作 用,“)”可视为自相应左括弧开始的 表达式的结束符。
// 从终端接收下一个字符
}
将从栈底到栈顶的字符传送至调用过程的数据区;
ClearStack(S);
// 重置S为空栈
if (ch != EOF) ch = getchar();
}

《数据结构(C语言)》第3章 栈和队列

《数据结构(C语言)》第3章 栈和队列
Data structures

❖ 栈的顺序存储与操作 ❖ 1.顺序栈的定义
(1) 栈的静态分配顺序存储结构描述 ② top为整数且指向栈顶元素 当top为整数且指向栈顶元素时,栈空、入栈、栈满 及出栈的情况如图3.2所示。初始化条件为 S.top=-1。
(a) 栈空S.top==-1 (b) 元素入栈S.stack[++S.top]=e (c) 栈满S.top>=StackSize-1 (d) 元素出栈e=S.stack[S.top--]
/*栈顶指针,可以指向栈顶
元素的下一个位置或者指向栈顶元素*/
int StackSize; /*当前分配的栈可使用的以 元素为单位的最大存储容量*/
}SqStack;
/*顺序栈*/
Data structures

❖ 栈的顺序存储与操作 ❖ 1.顺序栈的定义
(2) 栈的动态分配顺序存储结构描述 ① top为指针且指向栈顶元素的下一个位置 当top为指针且指向栈顶元素的下一个位置时,栈空 、入栈、栈满及出栈的情况如图3.3所示。初始化条 件为S.top=S.base。
…,n-1,n≥0} 数据关系:R={< ai-1,ai>| ai-1,ai∈D,i=1,2
,…,n-1 } 约定an-1端为栈顶,a0端为栈底 基本操作:
(1) 初始化操作:InitStack(&S) 需要条件:栈S没有被创建过 操作结果:构建一个空的栈S (2) 销毁栈:DestroyStack(&S) 需要条件:栈S已经被创建 操作结果:清空栈S的所有值,释放栈S占用的内存空间
return 1;
}
Data structures

数据结构课件第3篇章栈和队列

数据结构课件第3篇章栈和队列

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

第3章 限定性线性表——栈和队列

第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)

第三章栈和队列精品PPT课件

第三章栈和队列精品PPT课件
23 1
11
3. 栈的弹出操作
pop (&S, e) //栈 S 已存在,压入元素 e
{ if (s.top== 0)
printf("栈空下溢");
else
{
e =S.ST[s.top];
S.top - -;
}
Top
return OK;
Top
}
2021/2/20
4 3
50 2
23 1
12
栈的链式存储
使用两个栈:
栈OPTR寄存运算符
(包括()和#)
栈OPND寄存操作数OP
2021/2/20
23
例如: #4+ 2 3 10 / 5 # +
#
4
OPTR OPND
2021/2/20
24
算符间的优先级关系
1 2 +

*
/ () #
+

*
/

=

#
=
2021/2/20
25
例如: #4+ 2 3 10 / 5 #
d4
c3
b2
栈底
a1
top 7
栈的顺序存储
# define Maxsize 100+1
typedef struct {
s
elemtype ST[Maxsize] 栈顶
int top;
top
d4
} stack;
c3
stack S;
b2
2021/2/20
栈底
a1
top 8
栈的顺序存储
1.栈空的条件:
则实际有效的是下列两行: while (*s) putchar(*s++);

数据结构实用教程(C语言版) 第3章 栈和队列

数据结构实用教程(C语言版)  第3章 栈和队列
返回到本节目录
3.1.1 栈的概念
假设有一个栈S=(a1,a2,…,an),栈 中元素按a1,a2,…,an的次序进栈后, 进栈的第一个元素a1为栈底元素,出栈的第 一个元素an为栈顶元素,也就是出栈的操作 是按后进先出的原则进行的,其结构如图31所示。
图3-1栈结构示意图
返回到本节目录
3.1.2栈的基本操作
3.1.3顺序栈
由于栈是操作受限制的线性表,因此与线性表类似,栈也 有两种存储结构,即顺序存储结构和链式存储结构。 1. 顺序栈的定义 栈的顺序存储结构称为顺序栈。类似于顺序表的类型定义,顺 序栈是用一个预设的足够长度的一维数组和一个记录栈顶元素 位置的变量来实现。顺序栈中栈顶指针与栈中数据元素的关1.3顺序栈
3. 顺序栈的基本操作实现
(3)进栈操作 进栈操作的过程如图3-3所示。先判断栈S如图3-3(a) 是否为满,若不满再将记录栈顶的下标变量top加1如 图3-3(b),最后将进栈元素放进栈顶位置上如图33(c)所示,算法描述见算法3.3。
图3-3 进栈操作过程图
返回到本节目录
栈除了在栈顶进行进栈与出栈外,还有初始化、判空 等操作,常用的基本操作有: (1)初始化栈InitStack(S)。其作用是构造一个空 栈 S。 (2)判断栈空EmptyStack(S)。其作用是判断是 否是空栈,若栈S为空,则返回1;否则返回0。 (3)进栈Push(S,x)。其作用是当栈不为满时,将 数据元素x插入栈S中,使其为栈S的栈顶元素。 (4)出栈Pop(S,x)。其作用是当栈S不为空时,将 栈顶元素赋给x,并从栈S中删除当前栈顶元素。 (5)取栈顶元素GetTop(S,x)。其作用是当栈S不 为空时,将栈顶元素赋给x并返回,操作结果只是 读取栈顶元素,栈S不发生变化。 返回到本节目录

第3章栈和队列

第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章数据结构栈和队列

第3章数据结构栈和队列

第3章数据结构栈和队列数据结构是计算机科学中重要的基础知识之一,它是用于组织和管理数据的方法。

栈和队列是其中两种常见的数据结构,它们分别以后进先出(Last In First Out,LIFO)和先进先出(First In First Out,FIFO)的方式操作数据。

本文将详细介绍栈和队列的概念、特点以及应用。

一、栈栈是一种限制仅在表尾进行插入和删除操作的线性表。

插入和删除操作称为入栈和出栈,即数据项的入栈相当于把数据项放入栈顶,而数据项的出栈相当于从栈顶移除数据项。

栈具有后进先出的特点,即后入栈的数据项先出栈,而最先入栈的数据项最后出栈。

类比现实生活中的例子就是一叠盘子,我们只能从最上面取盘子或放盘子。

栈的实现方式有两种:基于数组和基于链表。

基于数组的栈实现相对简单,通过一个数组和一个指向栈顶的指针来完成栈的操作。

基于链表的栈实现则需要定义一个节点结构,每个节点包含一个数据域和一个指向下一个节点的指针,通过头指针来操作栈。

栈的应用非常广泛,比如浏览器中的返回功能就是通过栈来实现的。

当我们点击浏览器的返回按钮时,当前页面会入栈,点击前进按钮时,当前页面会出栈。

在编程中,栈也被广泛应用,比如函数调用栈用于存储函数调用的上下文信息。

二、队列队列是一种限制仅在表头删除和在表尾插入的线性表。

表头删除操作称为出队列,表尾插入操作称为入队列。

和栈不同,队列采用先进先出的原则,即最先入队列的元素最先出队列。

队列的实现方式也有两种:基于数组和基于链表。

基于数组的队列实现和栈类似,通过一个数组和两个指针(一个指向队头,一个指向队尾)来完成队列的操作。

基于链表的队列实现则需要定义一个节点结构,每个节点包含一个数据域和一个指向下一个节点的指针,通过头指针和尾指针来操作队列。

队列同样具有广泛的应用,比如操作系统中的进程调度就是通过队列来实现的。

CPU会按照进程到达的顺序,依次从队列中取出进程进行执行。

在编程中,队列也常用于解决一些需要按顺序处理数据的问题。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

3*2=6 2*1=2 1
1 * Fact(0)
3.3 栈与递归的实现
递归算法的思想
• 要解决规模为n的问题,可通过解决规模为n-1的问题实现; 要解决规模为n的问题,可通过解决规模为n • 当问题规模为1(或某一确定值)时,问题直接可解。 当问题规模为1 • 该思想类似于数学归纳法思想。
3.3 栈与递归的实现
1. 保存被调函数计算结果 2. 释放被调函数的数据区 3. 依照被调函数保存的返回地址将控制转移至调用函数
3.3 栈与递归的实现
当函数嵌套调用时
void first(int s,int t); void second(int d); void main(){ int m,n; , ; first(m,n); 1:……} int first(int s,int t){ int i; second(i); 2:……} int second(int d){ int x,y; ……} m n
3.4 队列
• 基本操作 InitQueue(&Q) 构造一个空队列Q InitQueue(&Q) 构造一个空队列Q DestroyQueue( DestroyQueue(Q) 销毁队列Q 销毁队列Q ClearQueue(&Q)清空队列Q ClearQueue(&Q)清空队列Q QueueEmpty( )判断队列Q QueueEmpty(Q)判断队列Q是否为空 QueueLength( QueueLength(Q)求队列长度 GetHead( GetHead(Q,&e)取队列头元素 &e)取队列头元素 EnQueue(&Q, EnQueue(&Q,e)在队尾插入元素 DeQueue(&Q,&e)删除Q DeQueue(&Q,&e)删除Q的队头元素 QueueTraverse( QueueTraverse(Q,visit()) 遍历队列元素 visit()) • }ADT Queue
• 汉诺塔递归过程动态演示
3.4 队列
日常生活中队列的例子
• 排队:先到先服务
最壮观的排队: 最壮观的排队: 图中的“黑线”为卫星 照片显示的天安门广场 上等待参观毛主席纪念 堂的队伍
3.4 队列
计算机中队列的例子
• 操作系统中的作业队列 • 网络打印机种的打印队列 • 媒体播放器的播放队列
当有多个任务提交给某一硬件或软 件处理时,通常在计算机内部形成 一个任务队列,按照先后顺序服务, 如打印队列,下载队列,音乐播放 队列等等。
第三章 栈和队列
3.3 栈与递归的实现
递归实例
• 一个古老的故事:
从前有座山,山上有座庙,庙里有个老和尚讲故事, 从前有座山,山上有座庙,庙里有个老和尚讲故事, 讲的什么故事呢? 讲的什么故事呢? 从前有座山,山上有座庙,庙里有个老和尚讲故事, 从前有座山,山上有座庙,庙里有个老和尚讲故事, …………
3.3 栈与递归的实现
当函数嵌套调用时
void first(int s,int t); void second(int d); void main(){ int m,n; first(m,n); ( , ); 1:……} int first(int s,int t){ int i; second(i); 2:……} int second(int d){ int x,y; ……} 1 m n i m n
X
Y
Z
将X上剩余的最大一个盘子直接移至Z
3.3 栈与递归的实现
Setp3
hanoi(n-1, y, x, z)
X
Y
Y上剩余的2个盘子 借助X全部移至Z
Z
3.3 栈与递归的实现
实现代码
• • 1. 2. 3. 4. 5. 6. 7. 8. 9. void hanoi (int n, char x, char y, char z) z) //将塔座x上从小到大的1 各盘子,经y移到z //将塔座x上从小到大的1-n各盘子,经y移到z。 { if (n = = 1) 1) move (x, 1, z); z); else { hanoi( hanoi(n-1, x, z, y); y) move( move(x, n, z); z) hanoi( hanoi(n-1, y, x, z); z) } }
3.4 队列
双端队列简介
删除 插入 插入
双端队列
a1 a2 a3 a4 …… an 端1 端2
删除
删除
插入
输入受限
a1 a2 a3 a4 …… an 端1 端2
删除
插入 插入
输出受限
a1 a2 a3 a4 …… an 端1 端2
删除
3.4 队列
链队列——队列的链式表示和实现 链队列——队列的链式表示和实现
3.3 栈与递归的实现
当函数嵌套调用时
void first(int s,int t); void second(int d); void main(){ int m,n; first(m,n); 1:……} int first(int s,int t){ int i; second(i); 2:……} : int second(int d){ int x,y; ……} 2 1 i m n x y i m n
Out
a1 a2 a3 a4 …… an
In an …… a2 a1
Front
Rear
3.4 队列
队列的抽象数据类型定义
• ADT Queue { • 数据对象:D 数据对象:D = { ai | ai ∈ElemSet,i = 1, 2, …, n } ElemSet, • 数据关系:R1 数据关系:R1 = { < ai-1, ai > ai-1, ai ∈D, i = 1, 2, …, n } aiai约定其中a 为队头,a 约定其中a1为队头,an为队尾。 •
3.3 栈与递归的实现
当函数嵌套调用时
void first(int s,int t); void second(int d); void main(){ int m,n; first(m,n); 1:……} int first(int s,int t){ int i; second(i); ( ); 2:……} int second(int d){ int x,y; ……} 2 1 i m n x y i m n
3.3 栈与递归的实现
当函数递归调用时
• 递归的层次
设调用递归函数的主函数为0层 设调用递归函数的主函数为 层 每进行一次递归调用,层数增 每进行一次递归调用,层数增1 当开始从最内层函数返回时, 当开始从最内层函数返回时, 没返回一层,层数减 没返回一层,层数减1 后调用, 后调用,先返回
调 用 归 递 第n层递归调用参数 返 回 第n-1层递归调用参数 …… 第2层递归调用参数 第1层递归调用参数 归 递
3.3 栈与递归的实现
函数调用的内部机制
• 函数A运行期间调用函数B 函数A运行期间调用函数B之前要做的三件事:
1. 将实参、返回地址传递给被调函数 将实参、 2. 为被调函数的局部变量分配存储区 3. 将控制转移到被调函数入口地址

从被调函数B返回调用函数A 从被调函数B返回调用函数A之前要做的三件事:
3.4 队列
队列的删除操作
data Q.front Q. rear P next data next ^
• • • • • • • • • • • • •
Status DeQueue(LinkQueue &Q,QElemType &e) { QueuePtr p; if( Q.front==Q.rear ) return ERROR; p=Q.front->next; //修改头指针,完成一般的删除操作 e=p->data; Q.front->next=p->next; if(Q.rear==p) //考虑特殊情况:当被删除的元素为最后一个时 Q.rear=Q.front; free(p); return OK; }
3.4 队列
队列的插入操作
data Q.front Q. rear next data next ^
• Status EnQueue(LinkQueue &Q,QElemType e) • { • QueuePtr p=(QueuePtr)malloc(sizeof(QNode)); • if(!p) exit(OVERFLOW); /* 存储分配失败 */ • p->data=e; • p->next=NULL; • Q.rearQ.rear->next=p; • Q.rear=p; • return OK; • }
3.4 队列
想一想:队列的本质特点是什么?
• 先进先出 First In First Out • 一端只出,一端只入
Out
a1 a2 a3 a4 …… an
In
Front
Rear
3.4 队列
对列与栈的比较
• 相同点:都是线性表的特例 • 不同点:
队列: 先进先出; 两个出入口:一端只出,一端只入; 队列: 先进先出; 两个出入口:一端只出,一端只入; 后进先出; 一个出入口:同一端入,同一端出。 栈: 后进先出; 一个出入口:同一端入,同一端出。
汉诺塔问题
X
Y
Z
借助Y柱, 将X柱上的三个盘子全部移至Z柱, 任何时候都不得将大盘放在小盘上面
3.3 栈与递归的实现
Step 1
hanoi(n-1, x, z, y)
XLeabharlann YZ要想解决将3个盘子从X经Y全部移至Z 先解决将2个盘子从X经Z全部移至Y
3.3 栈与递归的实现
相关文档
最新文档