数据结构课件-第三章

合集下载

数据结构教程(章 (3)

数据结构教程(章 (3)

调函数
if(s->top==-1)
printf("Stack is empty!\n"); //栈为空
else
{
*x=s->data[s->top];
//栈顶元素出栈
s->top--;
//栈顶指针
top减1
}
}
第3章 栈 和 队 列
5) 取栈顶元素 取栈顶元素操作除了不改变栈顶指针外,其余操作与出栈
请一个结点空间
p->data=x;
//读入结点数据
p->next=*top;
//该结点作为栈顶元素链
入链栈 *top=p;
顶元素 }
//栈顶指针指向这个新栈
第3章 栈 和 队 列
4) 出栈
算法如下:
void Pop_LinkStack(StackNode **top,datatype *x)
{
StackNode *p;
//栈
已满
else
{
s->top++;
//先使栈顶指
针top增1
s->data[s->top]=x;
//再将元素x压入栈*s

}
}
第3章 栈 和 队 列
4) 出栈
算法如下:
void Pop_SeqStack(SeqStack *s,datatype *x)
{
//将栈*s中的栈顶元素出栈并通过参数x返回给主
3. 链栈 栈的链式存储结构又称链栈。为了克服顺序栈容易出现上 溢的问题,可采用链式存储结构来构造栈。由于链栈是动态分 配元素存储空间的,因此操作时无需考虑上溢问题。这样,多 个栈的共享问题也就迎刃而解了。 由于栈的操作仅限制在栈顶进行,也即元素的插入和删除 都是在表的同一端进行的,因此不必设置头结点,头指针也就 是栈顶指针。链栈的示意图如图3-4所示。

精品课件-数据结构(刘肖)-第3章

精品课件-数据结构(刘肖)-第3章

第3章 栈与队列 图3-2 顺序栈的状态及进栈、出栈操作
第3章 栈与队列
可见栈空和栈满是进行栈操作的两个限制条件。 栈空条件:s->top = 0,此时不能进行出栈操作。 栈满条件:s->top = Maxsize -1,此时不能进行进栈操作。 2.栈的基本运算的实现 算法3-1 初始化。 栈的初始化即创建一个空栈。可通过指针变量获取该空栈。 算法描述如下:
第3章 栈与队列
该类型包含两部分内容:一个是存放栈中数据元素的data 数组,另一个是标记栈顶位置的top。在C语言的描述中,我们 可约定data数组中的data[0]单元不用,并用top=0表示栈空, 这也是初始化栈的状态。在实际应用时,只需声明一个属于上 述类型的栈变量,即可对此变量进行栈的有关操作。
(2) 在日常生活中,为了维持正常的社会秩序而出现的 常见现象是排队,计算机系统中也要解决各种任务的有序等待 问题,因此,设计一种队列结构来描述和解决此类问题将是必 要的和有效的。
本章我们就来学习栈与队列这两种结构及其在实际中的应 用。
第3章 栈与队列 知识要点
(1) 栈与队列的逻辑结构; (2) 栈与队列的顺序存储结构及链式存储结构; (3) 栈与队列的基本运算。 能力要求 应用栈与队列的基本运算解决计算机应用中的一些实际问 题。
第3章 栈与队列
3.1 栈
3.1.1 栈的定义及基本运算
第3章 栈与队列 生活中,我们都有洗盘子和取用盘子的经验,通常是将洗
好的盘子叠放在一起,放的时候是最先洗好的盘子放在最下面, 之后每洗完一个盘子,就将其累放在这叠盘子的最上面。取用 的时候是先取用最上面的盘子(即最后放置的盘子),之后依次 取用放在顶部的盘子,而第一个放置的盘子最后一个被取用。 这个过程的特点就是最后放置的盘子最先取用,而最先放置的 盘子最后取用。那么,描述和解决类似这样放入次序和使用次 序相反的问题应采用什么样的数据结构呢?答案是“栈”结构。

数据结构课件第3章

数据结构课件第3章

0
1
2
3
4
5
6
7
a1
a2
a3
a4
a5
a6
a7
队头 F=0
队尾 R=7
a3 2 1 3 0 4 7 a3 5 6 3 a2 2 1 a1 0 F=0 a4 4 a5 5 6 a6 7 a7 R=0 R=7 3 a2 2 1 a1 0
a4 4 a5 5 6 a6 7
a8
F=0
a7
R=0
F=0
删除所有元素
top X W … B top
top=0 空栈
top
W

B A
top=m-1 元素X出栈
top
A
A
top=m 满栈
top=1 元素A入栈
例:堆栈的插入、删除操作。 出栈操作程序如下: # define m 1000; /*最大栈空间*/ 出栈操作算法: 1)栈顶指针top是否为0: typedef struct stack_stru 若是,则返回;若不是, { int s[m]; int top; }; 则执行2。 void pop (stack, y) 2)将栈顶元素送给y, struct stack_stru stack; 栈顶指针减1。 int *y; { if (stack.top = = 0) printf (“The stack is empty ! \n”); top Y Y else { top B B *y=stack.s[stack.top]; A A stack.top - -; } 出栈操作 }
top=p;
} 栈的入栈、出栈操作的时间复杂度都为O(1)。
栈的应用
一、 表达式求值 表达式由操作数、运算符和界限符组成。 运算符可包括算术运算符、关系运算符、逻辑运算符。

数据结构ppt3

数据结构ppt3

54
6
6
到一位8进制数则进栈
6
0
6
保存,转换完毕后依
所以:(3456)10 =(6613)8
次出栈则正好是转换 结果。
3.1 栈
3.1.4 栈的应用实例
例3.4
算法设计: 当N>0时,重复(1),(2):
(1)若 N≠0,则将N % r 压入栈s中 ,执行2;若N=0,将栈 s的内容依次出栈,算法结束。
3.1 栈
3.1.1 栈的定义和运算
栈的定义:
栈是只能在一端进行插入和删除的线性表(运算受限)。 由此,栈具有后进先出(LIFO)的特性。
入栈(插入)
栈顶元素
an

a2 a1
出栈(删除) 栈顶:插入、删除的一端
栈底:栈顶的另一端
3.1 栈
3.1.1 栈的定义和运算
栈的基本运算:
(1) 初始化栈init_stack(S): 设置栈S为空。
量top来标识栈顶位置。 类型定义如下:
#define maxsize 50 typedef struct
{ elementtype data[maxsize]; int top;
} seqstack; //定义了一个栈类型seqstack seqstack s1,*s; //定义了栈变量s1和指向栈类型的指针s
为此,可采用循环结构来解决,即将Q->data[0]做为Q>data[maxsize-1]的下一个存储位置——循环队列。
3.2 队列
3.2.2 顺序队列与循环队列
1、存储结构
Q->rear
1
Q->data: 0
maxsize-1
Q->front

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

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

else
{
s.top++;
s.stack[s.top]=x;
}
}
******上课时请保持课堂的安静,谢谢大家!!!
30.10.2020
× 第11页
数据结构 电子教案 — [ 湖北汽车工业学院 软件教研室 马春江 特别制作 ] 首页 尾页 上页 下页 范例 讨论 考题 帮助 关于 结束
(3)退栈
void pop(seqstack &s)
30.10.2020
× 第9页
数据结构 电子教案 — [ 湖北汽车工业学院 软件教研室 马春江 特别制作 ] 首页 尾页 上页 下页 范例 讨论 考题 帮助 关于 结束
2、栈的五种运算
(1)初始化栈
void inistack(seqstack &s)
{
s.top=0;}源自******上课时请保持课堂的安静,谢谢大家!!!
×
首页 尾页 上页 下页 范例 讨论 考题 帮助 关于 结束
主要内容 栈
队列
这两种结构都是特殊的线性表
******上课时请保持课堂的安静,谢谢大家!!!
30.10.2020
第2页
数据结构 电子教案 — [ 湖北汽车工业学院 软件教研室 马春江 特别制作 ]
×
首页 尾页 上页 下页 范例 讨论 考题 帮助 关于 结束
Operation:
Void inistack(&s) //将栈S置为一个空栈(不含任何元素)
Void Push(&s,x) //将元素X插入到栈S中,也称为 “入栈”、 “插 入”、 “压入”
Void Pop(&s) //删除栈S中的栈顶元素,也称为”退栈”、 “删 除”、 “弹出”

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

数据结构3栈和队列PPT教学课件

数据结构3栈和队列PPT教学课件

~AStack() { delete [] elements; } // Destructor
void clear() { top = 0; }
注意:这里top在第I个位置
2020/12/12
8
一些重要的条件
栈满:top==maxSize-1; 栈空:top==-1
2020/12/12
9
链式栈
{
private:
int MaxSize;
// 栈中最大元素个数
int top;
// 栈中实际元素个数
T *elements; // 存储栈元素的数组
public:
AStack(int sz =DefaultListSize) // Constructor
{ size = sz; top = 0; elements = new T[sz]; }
virtual void MakeEmpty() = 0; virtual int isEmpty() virtual int isFull()=0
};
2020/12/12
5
顺序栈
由于栈是运算受限的线性表,因此 线性表的存储结构对栈也适应。
栈的顺序存储结构简称为顺序栈, 它是运算受限的线性表。因此,可用 数组来实现顺序栈。因为栈底位置是 固定不变的,所以可以将栈底位置设 置在数组的两端的任何一个端点;栈 顶位置是随着进栈和退栈操作而变化 的,故需用一个整型变量top
时间上:顺序栈为O(1),链式栈为O(1) 空间上:顺序栈要一个固定的长度,当栈不够
满时,空间浪费;链式栈长度可变,但对于每 个元素需要一个链接域,产生结构性开销。 何时使用顺序栈? 当要实现多个栈时,可用一个数组存储两个栈, 且最好是一个栈增长时另一个栈缩短。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

{k=n%r ;push(S,k);n/=r;}
while(!StackEmpty(S))
{pop(S,k);printf(“%d ”,k);}
}
例3.3 表达式中括号匹配问题。假设一个算术表达 式中包含圆括号、方括号和花括号三种类型的括号 ,编写一个判别表达式中括号是否正确配对的算法

算法思想:算术表达式中三种括号出现的次序 正好符合后到的括号要最先被匹配的“后进先 出”的栈的操作特点,因此可以利用一个栈来 存储三种左括号。当右括号出现时,看当前栈 顶括号是否与之匹配,若匹配则退栈,若不匹 配说明算术表达式中括号配对不正确。若算术 表达式中所有括号都能正确的别消解,则改算 术表达式中括号配对正确,否则该算术表达式 中括号配对不正确。用顺序栈实现如下 :
if((Sq->rear+1)%MAXSIZE==Sq->front) return 0; /*若循环队 列已满*/ Sq->elem[Sq->rear]=x; /*若循环队列未满,则先插入元素, 后将尾指针后移*/ Sq->rear=(Sq->rear+1)%MAXSIZE; return 1; }
数据结构
主编 许绘香 段明义 中国水利水电出版社
第三章 栈和队列
栈和队列是两种特殊的线性结构。从数据的结 构角度看,它们是线性表,从操作的角度看, 它们是操作受限的线性表。在日常生活中经常 会遇到栈或队列的实例。例如,停车场车辆的 调度要用到栈,排队购物要用到队列。
3.1工作场景导入
【工作场景】 某公司有一个地下停车场如图3-1-1,此停车场是一个可停 放n辆汽车的狭长通道,且只有一个大门可供汽车进出.汽车在停车 场内按照车辆到达时间的先后顺序, 依次从停车场最里向大门口 处停放(最先到达的第一辆车放在停车场的最里面)。 若车场内已 停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开 走,则排在便道上的第一辆车即可开入;当停车场内的某辆车要开 走时,在它之后进入的车辆必须退出车场为它让路,待该辆车开出 大门外,其他车辆再按照原次序进入车场,每辆车停放在车场的车 在它离开停车场时必须按照它停留的时间长短交纳费用. 如果停 留在便道上的车未进停车场就要离去,允许其离去,不收停车费, 并且仍然保持在便道上等待的车辆次序。编制程序模拟该停车场
的管理。
3.2.1 栈的定义及基本运算
•栈(Stack),是一种运算受限的线性表,即它只 允许在表的一端进行插入和删除操作。通常,我们 把这一端称为栈顶(Top),另一端称为栈底 (Botton)。当栈中没有元素时称为空栈。 向栈中插入新元素的过程称为进栈或入栈;
从栈中删除元素的过程称为出栈或退栈
回其值。
3.2.2 栈的表示和实现
1 利用一组地址连续的存储单元依次存放自栈底到栈顶
的数据元素,在高级程序设计语言中,通常以一固定 大小的一维数组来表示顺序栈。栈的顺序存储结构为
typedef struct{ ElemType elem[MAXSIZE]; int top;
}SqStack;
if (StackEmpty(S) ) && ( tag == 1 ) ) printf( "\n括弧正确配对 !\n"); /*如果栈为空且 tag 为1,则打印配对成功*/
else printf( "括弧不正确配对 !\n"); /*如果栈不空或者 tag 为0,则打印配对不成功*/
}
3.3 队列
while ( ( ch !='#' ) && ( tag == 1 ) ) /*如果字符串没有结束且标志位为 1,则做如下操作*/
{ if ( ch == '(' || ch == '['|| ch == '{') Push ( S, ch ); /*如果遇到 ' ( '、' [ ' 或 ' { ',则将其入栈 */
3 出列操作 int DeQueue(SqQueue *Sq, ElemType *x) { if(Sq->front==Sq->rear) return 0; /*若循环队列已空
*/ *x=Sq->elem[Sq->front]; Sq->front=(Sq->front+1)%MAXSIZE; return 1;
#define MAXSIZE 100 //队列的最大容量 typedef struct { ElemType elem[MAXSIZE] ; //队列的存储空间 int front,rear ; //队头队尾指针 }SqQueue;
当front=rear时队列为空队列。
当rear=MAXSIZE时,队列已经无法再插入元素了,但 是实际上前面还有空的位置可供元素插入。通常将该 现象称为假溢出。这种现象致使被删除元素的空间无 法重新利用。
为充分利用向量空间,克服上述“假溢出”现象 ,可以将队列空间看成为一个首尾相接的圆环, 并称这种队列为循环队列(Circular Queue)。
循环队列循环队列的基本操作的实现
1 初始化操作 void Init_SeQueue(CirSeQueue *sq) { sq->front=sq->rear=0 ; } 2 入列操作 int EnQueue(SqQueue *Sq, ElemType x) { /*在循环队列Sq的尾部插入一个新的元素x*/
{ ElemType data; /*结点的数据域*/
struct SNode *next;
/*结点的指针域*/
}SNode,*Link; /*Link为结点指针类型*/
链栈操作示意图
3.2.3 栈的简单应用
例3.1:设计算法,实现把十进制整数用2-9之间 的任一进制数输出。
由计算过程可知,由低到高依次得到r进制中
if ( ch == ')' ) /*如果遇到 ' ) ',则弹出栈顶字符;若栈顶字符不等于 ' ( ',则置 tag 为 0 */
{ Pop (Leabharlann S, &x);if (x != '(' ) tag = 0; } /* if ( ch = ' ) ' ) 结束 */
if ( ch == ']' ) /* 如果遇到 ' ] ',则弹出栈顶字符;若栈顶字符不等于 ' [ ',则置 tag 为 0 */
{printf(″栈上溢出!\n″); return 0;} else{
/*否则将x赋值给栈顶指针所指空间,然后将栈顶指针 后移*/
S->elem[S->top]=x; S->top++; return 1; } }
(4
int Pop(SqStack *S,ElemType *x){
/*从栈中弹出栈顶元素*/
的每一位数字,而输出却是从高到低依次输
出每一位,所以此类问题正符合栈后进先出
的思想,适合用栈来解决此类问题,具体算
法描述如下:
void Alter(long n,int r)
{ Link S;
/*假定使用链栈*/
InitStack (S); /*初始化栈*/
while(n) /*由低到高求出每一个余数并入栈
S->top=0; } (2 int StackEmpty(SqStack *S){ /*判断栈S是否为空,空则返回1,非空则返回0*/
if(S->top==0)/*栈空条件为S->top==0*/ return 1; else return 0; }
(3 int Push(SqStack *S, ElemType x){ /*若栈S未满,则将元素x进栈*/ if(S->top==MAXSIZE) /*栈满条件为S->top==MAXSIZE*/
void Correct (SqStack *S) /*判别表达式中括弧是否正确配对*/
{ int tag; char ch, x;
InitStack(S); printf("请输入算术表达式,检查其括弧是否正确配对,以#结束,如 {5*[b-(c+d)]}# \n");
ch = getchar( ); tag = 1;/* 标志位。tag = 1,表达式中括弧正确配对;tag = 0 表达式中括弧不正确配对*/
FALE。 StackLength(S):栈S已存在,返回S的元素个数,即栈的长度。 GetTop(S, &e):栈S已存在且非空,用e返回S的栈顶元素。 Push(&S, e):栈S已存在,插入元素e为新的栈顶元素。 Pop(&S, &e):栈S已存在且非空,删除S的栈顶元素,并用e返
(1)InitQueue(Q (2)Empty(Q)判空操作 (3)EnQueue(Q,x)入队列操作 (4)DeQueue(Q)出队列操作 (5)GetHead(Q (6)Clear(Q (7)Currentsize(Q)
3.3.2 队列的顺序存储表示
利用一组连续的存储单元(一维数组) 依次存放从 队首到队尾的各个元素,称为顺序队列。由于随着 入队和出队操作的变化,队列的队头和队尾的位置 是变动的,因此设置两个整型变量front和rear分别 指示队头和队尾在数组空间中的位置 ,其类型定义 如下:
栈又被称为后进先出(Last In First Out)的线性 表,简称为LIFO表
栈的基本操作:
InitStack(&S):构造一个空栈S。 DestroyStack(&S):栈S已存在,将栈S销毁。 ClearStack(&S):栈S已存在,将S清为空栈。 StackEmpty(S):栈S已存在,若栈S为空栈,则返回TRUE,否则
相关文档
最新文档