数据结构-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
数据结构C语言描述(耿国华)第3章
操作前提: 栈S已经存在。
操作结果:取栈S的顶部元素。与Pop(S, x)不同之处在于 GetTop(S,x)不改变栈顶的位置。
第 3 章 限定性线性表——栈和队列
3.1.2 栈的表示和实现
1. 顺序栈 顺序栈是用顺序存储结构实现的栈,即利用一组地址连 续的存储单元依次存放自栈底到栈顶的数据元素,同时由于 栈的操作的特殊性, 还必须附设一个位置指针top(栈顶指针) 来动态地指示栈顶元素在顺序栈中的位置。通常以top=-1表 示空栈。顺序栈的存储结构可以用C语言中的一维数组来表 示。 栈的顺序存储结构定义如下:
if(S->top[0]+1==S->top[1]) /*栈已满*/ return(FALSE);
switch(i) { case 0:
S->top[0]++;
第 3 章 限定性线性表——栈和队列 S->Stack[S->top[0]]=x; break;
case 1: S->top[1]--; S->Stack[S->top[1]]=x; break;
否则为FALSE。
第 3 章 限定性线性表——栈和队列 5 Push(S,x)
操作前提:栈S已经存在。
操作结果:在S的顶部插入(亦称压入)元素x;若S栈未满,将x 插入栈顶位置,若栈已满,则返回FALSE,表示操作失败,否则 返回TRUE。
6 Pop(S, x)
操作前提:栈S已经存在。
操作结果:删除(亦称弹出)栈S的顶部元素,并用x带回该值; 若栈为空,返回值为FALSE,表示操作失败,否则返回TRUE。
X = N mod d (其中mod为求余运算) N = N div d (其中div为整除运算)
《数据结构(C语言)》第3章 栈和队列
栈
❖ 栈的顺序存储与操作 ❖ 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
栈
数据结构-c语言描述高等教育出版社耿国华
数据结构-c语言描述高等教育出版社耿国华第1章绪论习题一、问答题1. 什么是数据结构?2. 四类基本数据结构的名称与含义。
3. 算法的定义与特性。
4. 算法的时间复杂度。
5. 数据类型的概念。
6. 线性结构与非线性结构的差别。
7. 面向对象程序设计语言的特点。
8. 在面向对象程序设计中,类的作用是什么?9. 参数传递的主要方式及特点。
10. 抽象数据类型的概念。
二、判断题1. 线性结构只能用顺序结构来存放,非线性结构只能用非顺序结构来存放。
2. 算法就是程序。
3. 在高级语言(如C、或PASCAL)中,指针类型是原子类型。
三、计算下列程序段中X=X+1的语句频度for(i=1;i<=n;i++)for(j=1;j<=i;j++)for(k=1;k<=j;k++)x=x+1;[提示]:i=1时:1 = (1+1)×1/2 = (1+12)/2i=2时:1+2 = (1+2)×2/2 = (2+22)/2i=3时:1+2+3 = (1+3)×3/2 = (3+32)/2…i=n时:1+2+3+……+n = (1+n)×n/2 = (n+n2)/2f(n) = [ (1+2+3+……+n) + (12 + 22 + 32 + …… + n2 ) ] / 2 =[ (1+n)n/2 + n(n+1)(2n+1)/6 ] / 2=n(n+1)(n+2)/6=n3/6+n2/2+n/3区分语句频度和算法复杂度:O(f(n)) = O(n3)四、试编写算法求一元多项式Pn(x)=a0+a1x+a2x2+a3x3+…a n x n的值P n(x0),并确定算法中的每一语句的执行次数和整个算法的时间复杂度,要求时间复杂度尽可能的小,规定算法中不能使用求幂函数。
注意:本题中的输入a i(i=0,1,…,n), x和n,输出为P n(x0).通常算法的输入和输出可采用下列两种方式之一:(1)通过参数表中的参数显式传递;(2)通过全局变量隐式传递。
数据结构(C语言版)第3章栈
栈和队列是两种特殊的线性表,是操作 受限的线性表,称限定性数据结构。
栈 栈的应用 队列 队列的应用
3.1 栈(stack) stack)
一、 栈的定义:限定仅在表尾进行插入或删除操 栈的定义:限定仅在表尾进行插入或删除操 作的线性表,表尾—栈顶,表头—栈底,不含元 作的线性表,表尾—栈顶,表头—栈底,不含元 素的空表称空栈
3.2 栈的应用举例
由于栈结构具有的后进先出的固有特性, 致使栈成为程序设计中常用的工具。以下是 几个栈应用的例子。 一、栈的应用举例-----数制转换 一、栈的应用举例-----数制转换 十进制N 十进制N和其它进制数的转换是计算机 实现计算的基本问题,其解决方法很多, 实现计算的基本问题,其解决方法很多,其中 一个简单算法基于下列原理: 一个简单算法基于下列原理: N=(n div d)*d+n mod d ( 其中:div为整除运算,mod为求余运算) 其中:div为整除运算,mod为求余运算) 例如 (1348)10=(2504)8,其运算过程 如下:
答:
例4:计算机系2001年考研题(程序设计基础) 计算机系2001年考研题 程序设计基础) 年考研题( 设依次进入一个栈的元素序列为c 设依次进入一个栈的元素序列为c,a,b,d, 则可得到出栈的元素序列是: 则可得到出栈的元素序列是:
A)a A)a,b,c,d b C)b C)b,c,d,a c,d,b
链栈的进栈算法 LinkStack *PUSHLSTACK(LinkStack *top, ElemType x) { LinkStack *p; p=malloc(sizeof(LinkStack)); = p->data=x; p->next=top; = = return p; }
数据结构(C语言版)第三四章习题答案解析
第3章栈和队列习题1.选择题(1)若让元素1,2,3,4,5依次进栈,则出栈次序不可能出现在()种情况。
A.5,4,3,2,1 B.2,1,5,4,3 C.4,3,1,2,5 D.2,3,5,4,1(2)若已知一个栈的入栈序列是1,2,3,…,n,其输出序列为p1,p2,p3,…,pn,若p1=n,则pi为()。
A.i B.n-i C.n-i+1 D.不确定(3)数组Q[n]用来表示一个循环队列,f为当前队列头元素的前一位置,r为队尾元素的位置,假定队列中元素的个数小于n,计算队列中元素个数的公式为()。
A.r-f B.(n+f-r)%n C.n+r-f D.(n+r-f)%n (4)链式栈结点为:(data,link),top指向栈顶.若想摘除栈顶结点,并将删除结点的值保存到x中,则应执行操作()。
A.x=top->data;top=top->link; B.top=top->link;x=top->link;C.x=top;top=top->link; D.x=top->link;(5)设有一个递归算法如下int fact(int n) { //n大于等于0if(n<=0) return 1;else return n*fact(n-1); }则计算fact(n)需要调用该函数的次数为()。
A. n+1 B. n-1 C. n D. n+2 (6)栈在()中有所应用。
A.递归调用 B.函数调用 C.表达式求值 D.前三个选项都有(7)为解决计算机主机与打印机间速度不匹配问题,通常设一个打印数据缓冲区。
主机将要输出的数据依次写入该缓冲区,而打印机则依次从该缓冲区中取出数据。
该缓冲区的逻辑结构应该是()。
A.队列 B.栈 C.线性表 D.有序表(8)设栈S和队列Q的初始状态为空,元素e1、e2、e3、e4、e5和e6依次进入栈S,一个元素出栈后即进入Q,若6个元素出队的序列是e2、e4、e3、e6、e5和e1,则栈S的容量至少应该是()。
数据结构(C语言描述) 第三章
淮海工学院 数据结构课程
淮海工学院 数据结构课程
多链栈示意图
淮海工学院 数据结构课程
多链栈 入栈示意图
淮海工学院 数据结构课程
多链栈 出栈示意图
淮海工学院 数据结构课程
.3 栈的应用举例
1. 过程的嵌套调用
主 程 序 r s r 子 过 程 1 s r t 子 过 程 2 t s r 子 过 程 3
/*双端顺序栈出栈操作。*/ 双端顺序栈出栈操作。 双端顺序栈出栈操作 int Pop(DqStack *S,StackElementType *x,int i) { /* 从i 号堆栈中弹出栈顶元素并送到 中 */ 号堆栈中弹出栈顶元素并送到x中 switch(i) { case 0: if(S->top[0]==-1) return(FALSE); *x=S->Stack[S->top[0]]; S->top[0]--; break; case 1: if(S->top[1]==M) return(FALSE); *x=S->Stack[S->top[1]]; S->top[1]++; break; default: return(FALSE); } return(TRUE); 淮海工学院 数据结构课程 }
3.1.1 栈的定义
定义: 定义:只允许在一端插入和删除的线性表 允许插入和删除的一端称为栈顶 允许插入和删除的一端称为栈顶 (top), , 端称为栈底 栈底(bottom) 另一 端称为栈底 特点: 特点: 后进先出 (LIFO)
进栈 栈 顶 出栈 ... an ……... a2 栈底 a1 栈s=(a1,a2,……,an)
淮海工学院数据结构课程淮海工学院数据结构课程淮海工学院数据结构课程多链栈示意图淮海工学院数据结构课程入栈示意图淮海工学院数据结构课程出栈示意图淮海工学院数据结构课程313栈的应用举例过程的嵌套调用淮海工学院数据结构课程原串字符与出栈字符依次比较若不等非回文若直到栈空都相等回文字符串
数据结构(C语言版CHAP3
S.top
n+1 n n-1 i-1 i-2
0
e an ai ai-1 a1
STA作图示
S.top
S.top n n-1 i-1 i-2 S.base 0
an ai ai-1
n+1 n n-1 i-1 i-2
e an
ai ai-1 a1
STACK_INIT_SIZE
3.1 栈
二 栈的基本操作 1) 初始化操作InitStack((&S) 功能:构造一个空栈S; 2) 销毁栈操作DestroyStack(&S) 功能:销毁一个已存在的栈; 3) 置空栈操作ClearStack(&S) 功能:将栈S置为空栈; 4) 取栈顶元素操作GetTop(S, &e) 功能:取栈顶元素,并用e 返回; 5)进栈操作Push(&S, e) 功能:元素e进栈; 6)退栈操作Pop(&S, &e) 功能:栈顶元素退栈,并用e返回; 7)判空操作StackEmpty(S) 功能:若栈S为空,则返回True,否则返回False; 第 9 页
S.top
n n-1
an
i-1 i-2
1 0
ai ai-1
a2 a1
STACK_INIT_SIZE
S.base
S.stacksize
第 13 页
3.1 栈
当栈用顺序结构存储时, 栈的基本操作如建空栈、 进栈、出栈等操作如何实现?
第 14 页
3.1 栈
二 顺序栈基本操作的算法 1)初始化操作InitStack_Sq((SqStack &S)
a1
STACK_INIT_SIZE
S.base S.stacksize
数据结构(C语言)_3
第三章栈和队列本章介绍的是栈和队列的逻辑结构定义及在两种存储结构(顺序存储结构和链式存储结构)上如何实现栈和队列的基本运算。
栈和队列:⑴从数据结构角度:操作受限的线性表——限定性的数据结构,其基本操作是线性表操作的子集;⑵从数据类型角度:与线性表不同的抽象数据类型(多型)。
两者的逻辑结构相同,但操作的种类和数目不同,用途大为不同。
本章的重点:掌握栈和队列在两种存储结构上实现的基本运算;难点:循环队列中对边界条件的处理。
3.1 栈一、抽象数据类型栈的定义栈(Stack):限定仅在表尾进行插入或删除操作的线性表。
栈的表尾称为栈顶,表头称为栈底,不含元素的空表称为空栈。
假设栈S=(a1,a2,a3,…an),则a1称为栈底元素,an为栈顶元素。
栈中元素按a1,a2,a3,…an的次序进栈,退栈的第一个元素应为栈顶元素。
换句话说,栈的修改是按后进先出的原则进行的。
因此,栈称为后进先出的线性表(Last In First Out ,LIFO)。
栈的抽象数据类型定义:ADT Stack{数据对象:D={ai|ai(- ElemSet,i=1,2,...,n,n>=0)数据关:R1={<ai-1,ai>|ai-1,ai(- D,i=2,...,n)基本操作:InitStack(&S) 构造一个空栈SDestroyStack(&S) 栈S存在则栈S被销毁ClearStack(&S) 栈S存在则清为空栈StackEmpty(S) 栈S存在则返回TRUE,否则FALSEStackLength(S) 栈S存在则返回S的元素个数,即栈的长度GetTop(S,&e) 栈S存在且非空则返回S的栈顶元素Push(&S,e) 栈S存在则插入元素e为新的栈顶元素——入栈Pop(&S,&e) 栈S存在且非空,则删除S的栈顶元素并用e返回其值——出栈StackTraverse(S,visit())栈S存在且非空,则从栈底到栈顶依次对S的每个数据元素调用函数visit(),一旦visit()失败,则操作失败}ADT Stack二、栈的表示和实现⒈顺序栈由于栈是运算受限的线性表,因此线性表的存储结构对栈也适应。
数据结构C语言 第3章
第3章 栈和队列 3.2.2栈的基本运算 栈的基本运算 (1)判栈空Empty(S). 若栈为空则返回"真",否则返回" 假"; (2)入栈操作(压栈)Push(S,x) 将新元素压入栈中,使其 成为栈顶元素; (3)出栈操作(弹栈)Pop(S,x) 若栈不空则返回栈顶元素, 并从栈中删除栈顶元素,否则返回NULL; (4)取栈顶元素 Pettop(s,x) 若栈不空则返回栈顶元素,否则 返回NULL; (5)置空栈Clear(s) 将当前栈设定为空栈; (6)求元素个数 CurrenSize(s) 求当前栈中元素的个数 .
第3章 栈和队列
3.3 顺序栈的存储结构及算法实现
3.3.1顺序栈 顺序栈 顺序栈利用一组连续的存储单元存放从栈底到栈顶的诸元 素.同时用一指针top指示当前栈顶元素的位置, C语言中用一 维数组来描述. #define maxsize N typedef struct {Datatype data[maxsize+1]; int top; } Stack;
第3章 栈和队列 表3.1 算符优先级表
p1 + * / ( ) @
+ > > > > < > <
> > > > < > <
* < < > > < > <
/ < < > > < > <
( < < < < <
) > > > > = >
@ > > > >
> =
数据结构-使用C语言 朱战立 第3章堆栈和队列
top
D top C B A
D C B A
top
D C B A
top
顺序栈出栈函数的核心语句: S->top --; d = S->stack[S->top];
17
例5、 设依次进入一个栈的元素序列为c,a,b,d,则 可得到出栈的元素序列是:
A)a,b,c,d C)b,c,d,a
B)c,d,a,b D)a,c,d,b
初始化堆栈S 堆栈S非空否 入栈 出栈 取栈顶数据元素
11
二、堆栈的顺序表示和实现 1、顺序(堆)栈
顺序存储结构的堆栈。
顺序栈S an an-1 …… 栈顶top
2、顺序栈的存储结构
它是利用一组地址连续的存储 单元依次存放自栈底到栈顶的数据 元素,同时设指针top指示当前栈顶 位置。
ai …… a1 a0
具体方法:顺序扫描算术表达式(表现为一个字符串), 当遇到三种类型的左括号时让该括号进栈; 1. 当扫描到某一种类型的右括号时,比较当前栈顶括号是 否与之匹配,若匹配则退栈继续进行判断; 2. 若当前栈顶括号与当前扫描的括号不相同,则左右括号 配对次序不正确; 3. 若字符串当前为某种类型左括号而堆栈已空,则右括号 多于左括号; 4. 字符串循环扫描结束时,若堆栈非空(即堆栈中尚有某 种类型左括号),则说明左括号多于右括号;否则,左 右括号匹配正确。
14
顺序栈S
高地址
栈顶top
an an-1 …… ai …… a1 a0 入栈口诀:堆栈指针top “先 压后加” : S[top++]=an 栈底base 出栈口诀:堆栈指针top “先 减后弹” : e=S[--top]
低地址
栈不存在的条件: base=NULL; 栈为空的条件 : base=top或top<=0; 栈满的条件 : top-base=MaxSize;
数据结构实用教程(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不发生变化。 返回到本节目录
数据结构---C语言描述-(耿国华)-课后习题答案
第一章习题答案2、××√3、(1)包含改变量定义的最小范围(2)数据抽象、信息隐蔽(3)数据对象、对象间的关系、一组处理数据的操作(4)指针类型(5)集合结构、线性结构、树形结构、图状结构(6)顺序存储、非顺序存储(7)一对一、一对多、多对多(8)一系列的操作(9)有限性、输入、可行性4、(1)A(2)C(3)C5、语句频度为1+(1+2)+(1+2+3)+…+(1+2+3+…+n)第二章习题答案1、(1)一半,插入、删除的位置(2)顺序和链式,显示,隐式(3)一定,不一定(4)头指针,头结点的指针域,其前驱的指针域2、(1)A(2)A:E、AB:H、L、I、E、AC:F、MD:L、J、A、G或J、A、G(3)D(4)D(5)C(6)A、C3、头指针:指向整个链表首地址的指针,标示着整个单链表的开始。
头结点:为了操作方便,可以在单链表的第一个结点之前附设一个结点,该结点的数据域可以存储一些关于线性表长度的附加信息,也可以什么都不存。
首元素结点:线性表中的第一个结点成为首元素结点。
4、算法如下:int Linser(SeqList *L,int X){ int i=0,k;if(L->last>=MAXSIZE-1){ printf(“表已满无法插入”);return(0);}while(i<=L->last&&L->elem[i]<X)i++;for(k=L->last;k>=I;k--)L->elem[k+1]=L->elem[k];L->elem[i]=X;L->last++;return(1);}5、算法如下:#define OK 1#define ERROR 0Int LDel(Seqlist *L,int i,int k){ int j;if(i<1||(i+k)>(L->last+2)){ printf(“输入的i,k值不合法”);return ERROR;}if((i+k)==(L->last+2)){ L->last=i-2;ruturn OK;}else{for(j=i+k-1;j<=L->last;j++)elem[j-k]=elem[j];L->last=L->last-k;return OK;}}6、算法如下:#define OK 1#define ERROR 0Int Delet(LInkList L,int mink,int maxk){ Node *p,*q;p=L;while(p->next!=NULL)p=p->next;if(mink<maxk||(L->next->data>=mink)||(p->data<=maxk)) { printf(“参数不合法”);return ERROR;}else{ p=L;while(p->next-data<=mink)p=p->next;while(q->data<maxk){ p->next=q->next;free(q);q=p->next;}return OK;}}9、算法如下:int Dele(Node *S){ Node *p;P=s->next;If(p= =s){printf(“只有一个结点,不删除”);return 0;}else{if((p->next= =s){s->next=s;free(p);return 1;}Else{ while(p->next->next!=s)P=p->next;P->next=s;Free(p);return 1;}}}第三章习题答案2、(1)3、栈有顺序栈和链栈两种存储结构。
数据结构(C语言版)第3章 栈和队列
typedef struct StackNode {
SElemType data;
S
栈顶
struct StackNode *next;
} StackNode, *LinkStack;
LinkStack S;
∧
栈底
链栈的初始化
S
∧
void InitStack(LinkStack &S ) { S=NULL; }
top
C
B
base A
--S.top; e=*S.top;
取顺序栈栈顶元素
(1) 判断是否空栈,若空则返回错误 (2) 否则通过栈顶指针获取栈顶元素
top C B base A
Status GetTop( SqStack S, SElemType &e) { if( S.top == S.base ) return ERROR; // 栈空 e = *( S.top – 1 ); return OK; e = *( S.top -- ); ??? }
目 录 导 航
Contents
3.1 3.2 3.3 3.4 3.5
栈和队列的定义和特点 案例引入 栈的表示和操作的实现 栈与递归 队列的的表示和操作的实现
3.6
案例分析与实现
3.2 案例引入
案例3.1 :一元多项式的运算
案例3.2:号匹配的检验
案例3.3 :表达式求值
案例3.4 :舞伴问题
目 录 导 航
top B base A
清空顺序栈
Status ClearStack( SqStack S ) { if( S.base ) S.top = S.base; return OK; }
数据结构(C语言版)第3章
2012-2-19
13
3.2 ADT 队列 3.2
1.队列的定义 队列也是一种运算受限的线性表。在这种线性表上, 队列也是一种运算受限的线性表。在这种线性表上, 插入限定在表的某一端进行,删除限定在表的另一端进行。 插入限定在表的某一端进行,删除限定在表的另一端进行。 允许插入的一端称为队尾,允许删除的一端称为队头。 允许插入的一端称为队尾,允许删除的一端称为队头。 特点:队列中数据元素的入队和出队过程是按照“ 特点:队列中数据元素的入队和出队过程是按照“先 进先出” 的原则进行的。因此,队列又称为“先进先出” 进先出” 的原则进行的。因此,队列又称为“先进先出” 的线性表,简称FIFO FIFO表 的线性表,简称FIFO表。
* 顺序栈的C语言描述如下: 顺序栈的C语言描述如下:
#define MaxSize 数组元素的最大个数 typedef struct { ElemType data[MaxSize]; data[MaxSize]; int top; top; }STACK; }STACK; ElemType 为栈中元素的数据类型。 为栈中元素的数据类型。 data域 为一个一维数组,用于存储栈中元素。 data域:为一个一维数组,用于存储栈中元素。 top域 栈顶指针。取值范围为0 MaxSizetop域:栈顶指针。取值范围为0~MaxSize-1。 top=- 表示栈空,top=MaxSize- 表示栈满。 top=-1表示栈空,top=MaxSize-1表示栈满。
1.栈的定义
栈stack是一种特殊的(有序表)线性表,插入 stack是一种特殊的 有序表)线性表, 是一种特殊的( 或删除栈元素的运算只能在表的一端进行, 或删除栈元素的运算只能在表的一端进行,称运算 的一端为栈顶,另一端称为栈底。 的一端为栈顶,另一端称为栈底。
数据结构-C语言描述(本科)第3章
第3章 堆 栈 和 队 列
第3章 堆 栈 和 队 列 队列的基本运算包括构造一个空队列,判定一个队列是 否为空队列,判定一个队列是否已满,在一个未满的队列中 插入一个新元素,从一个非空的队列中删除队头元素等。当 然我们还可以根据应用需要增加其它必要的队列运算,如求 队列的长度,清除一个队列,以及遍历一个队列等。队列的 抽象数据类型定义见ADT 3-2。
第3章 堆 栈 和 队 列
后置条件: 若堆栈已满,则返回TRUE,否则返回FALSE。 void Push(Stack *s, T x) 后置条件:若堆栈已满,则指示Overflow,否则值为x的新元素进栈,成 为栈顶元素。 void Pop(Stack *s) 后置条件:若堆栈为空,则指示Underfow,否则栈顶元素从栈中删除。 void StackTop(Stack s,T* x) 后置条件:若堆栈为空,则指示Underfow,否则在参数x中返回栈顶元素 值。 }
第3章 堆 栈 和 队 列
if (IsEmpty(s)) printf("Underflow"); else *x=s.Elements[s.Top]; } void main(void) { Stack s; T x; CreateStack(&s,10); Push(&s,10); Push(&s,15); PrintStack(s); /* 构造一个容量为10的空整数栈*/ /*在栈中依次压入元素10和15*/ /*显示栈中元素*/
第3章 堆 栈 和 队 列 在 上 面 定 义 的 结 构 类 型 Stack 中 , Top 是 栈 顶 指 针 , MaxStack为栈的最大允许长度,它应不大于整型常量MaxSize。 一维数组 Elements 用以存放队列中的元素,实现堆栈的顺序存 储。标识符BOOL被定义为整型。 程序3-1是ADT 3-1中规定的栈运算在顺序表示下的实现。 当堆栈为空时,令栈顶指针Top=-1。栈的容量MaxStack由用 户通过参数maxsize设定,但不能超过MaxSize。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第3章 堆 栈 和 队 列
第3章 堆 栈 和 队 列 队列运算需要两个指针,Front指向队头元素,Rear指向队 尾元素。MaxQueue为队列的最大允许长度,它应不大于整型常 量 MaxSize 。一维数组 Elments 用以存放队列中的元素,实现队 列的顺序存储。 初始状态下,我们将Front和Rear两个指针均置成-1,代表 空队列,见图3-6(a)。图中,f和r分别代表Front和Rear。
第3章 堆 栈 和 队 列
ADT 3-2 Queue{ 数据: 零个或多个元素的线性序列(a0,a1,...,an-1),其最大允许长度为MaxQueue。 运算: void CreateQueue(Queue * q,int maxsize); 后置条件:已构造一个空队列。 BOOL IsEmpty(Queue q) 后置条件: 若队列为空,则返回TRUE,否则返回FALSE。
第3章 堆 栈 和 队 列
3.2 队
3.2.1 队列ADT源自列队列是限定只能在表的一端插入元素,在表的另一端删除 元素的线性数据结构。允许插入元素的一端称队尾(rear),允 许删除元素的另一端称队头( front )。若队列中无元素,则称 为空队列。若给定队列 Q=(a0,a1,…,an - 1) ,则称 a0 是队头元素, an-1是队尾元素。若元素a0,…,an-1依次入队列,则元素出队列的 次序与入队列一致,a0出队列后,a1才能出队列,见图3-4。由于 队列的这种先进先出的特点,因此队列是先进先出( First In First Out-FIFO)的线性数据结构。
第3章 堆 栈 和 队 列 进栈操作是:首先令栈顶指针进一(++s->Top),然后将 新元素x存放在新的栈顶位置(s->Elements[++s->Top]=x)。出 栈操作只是简单地令栈顶指针退一(s->Top--;)。所有这些运 算均包含参数s。对于那些会改变堆栈内容的运算,参数s为指 针类型Stack*,否则为Stack类型。主程序main用于测试已实现 的栈运算,起着驱动程序的作用。请注意主程序应严格按照每 个函数的参数类型调用它们。对于Stack*类型的参数,其对应 的实参前必须加上取地址运算符&。主程序中使用的PrintStack (Stack s)函数,输出栈中元素值,我们将其留作练习,请自 行实现之。PrintElement(x)函数的功能见2.3.2节。
第3章 堆 栈 和 队 列 程序3-1 顺序栈实现 void CreateStack(Stack *s,int maxsize) { s->Top=-1; s->MaxStack=maxsize; } BOOL IsEmpty(Stack s) { return s.Top<0; } BOOL IsFull(Stack s) { return s.Top>=s.MaxStack-1; }
第3章 堆 栈 和 队 列
我们可以使用测试顺序栈完全相同的主程序作为测试链式 栈的驱动程序。只要链式栈实现的各栈运算的接口(即函数原 型)与ADT 3-1 Stack中定义的完全相同,则主程序中调用栈 函数的语句可以不加任何改动。这就是所谓的使用与实现分离。 实现的改变应不影响客户程序。这正是抽象数据类型的宗旨。
第3章 堆 栈 和 队 列
ADT 3-1 Stack { 数据: 零个或多个元素的线性序列(a0,a1,...,an-1),其最大允许长度为MaxStack。 运算: void CreateStack(Stack * s,int maxsize ); 后置条件:已构造一个空堆栈。 BOOL IsEmpty(Stack s) 后置条件: 若堆栈为空,则返回TRUE,否则返回FALSE。 BOOL IsFull(Stack s)
第3章 堆 栈 和 队 列
x=*InputElement(); Push(&s,x); /*调用InputElement函数接受新元素x,并 令其进栈*/ PrintStack(s); Pop(&s); Pop(&s); if(IsEmpty(s)) printf("Is empty."); else printf("Is not empty."); PrintStack(s); } /*显示栈中元素*/ /*显示栈中元素*/ /*在栈中依次弹出两个元素*/ /* 判断此时栈是否为空栈*/
第3章 堆 栈 和 队 列
第3章 堆 栈 和 队 列 栈的基本运算包括构造一个空堆栈,判定一个栈是否为空 栈,判定一个栈是否已满,在一个未满的栈中插入一个新元 素,从一个非空的栈中删除栈顶元素等。当然我们还可以根据 应用需要增加其它必要的栈运算,如求栈的长度,清除一个 栈,以及遍历一个栈等。堆栈的抽象数据类型定义见ADT 3-1。 函数CreateStack是抽象数据类型的构造函数,有时可以根据需 要定义多个构造函数。
第3章 堆 栈 和 队 列 3.2.2 队列的顺序表示 与堆栈一样,队列可以采用顺序存储,也可以采用链接存 储。当我们用一维数组存储队列时,被称为顺序队列 (sequential queue),图3-5是队列的顺序表示示意图。队列 的链接表示在下一小节讨论。 队列的顺序实现可以用下面的C语言结构定义: typedef struct queue{ int Front,Rear,MaxQueue; T Elements[MaxSize]; } Queue
第3章 堆 栈 和 队 列 在 上 面 定 义 的 结 构 类 型 Stack 中 , Top 是 栈 顶 指 针 , MaxStack为栈的最大允许长度,它应不大于整型常量MaxSize。 一维数组 Elements 用以存放队列中的元素,实现堆栈的顺序存 储。标识符BOOL被定义为整型。 程序3-1是ADT 3-1中规定的栈运算在顺序表示下的实现。 当堆栈为空时,令栈顶指针Top=-1。栈的容量MaxStack由用 户通过参数maxsize设定,但不能超过MaxSize。
第3章 堆 栈 和 队 列 void Push(Stack* s, T x) { if ( IsFull(*s)) printf("Overflow"); else s->Elements[++s->Top]=x; } void Pop(Stack* s) { if (IsEmpty(*s))printf("Underflow"); else s->Top--; } void StackTop(Stack s,T* x) {
第3章 堆 栈 和 队 列
if (IsEmpty(s)) printf("Underflow"); else *x=s.Elements[s.Top]; } void main(void) { Stack s; T x; CreateStack(&s,10); Push(&s,10); Push(&s,15); PrintStack(s); /* 构造一个容量为10的空整数栈*/ /*在栈中依次压入元素10和15*/ /*显示栈中元素*/
第3章 堆 栈 和 队 列 程序3-2 链式栈的进栈和出栈运算 void Push(Stack *s, T x) { Node* p=NewNode2(x); p->Link=s->Top; s->Top=p; } void Pop(Stack *s) { Node *p=s->Top; s->Top=p->Link; free(p); }
第3章 堆 栈 和 队 列
第3章 堆 栈 和 队 列
3.1 堆栈 3.2 队列 3.3* 表达式的计算 3.4* 递归和递归过程 3.5* 演示和测试 习题3
第3章 堆 栈 和 队 列
3.1 堆 栈
3.1.1堆栈ADT 堆栈(或栈)是限定插入和删除运算只能在同一端进 行的线性数据结构。允许插入和删除元素的一端称为栈顶 ( top ),另一端称为 栈底 ( bottom)。若栈中无元素,则为空 栈。若给定堆栈S=(a0,a1,…,an-1),则称a0是栈底元素,an-1是栈 顶元素。若元素 a0,…,an - 1 依次进栈时,则出栈的顺序与进栈相 反,即元素an-1必定最先出栈,然后an-2才能出栈(见图3-1)。 由于栈的这种后进先出的特点,因此栈是后进先出(Last In First Out-LIFO)的线性数据结构。
第3章 堆 栈 和 队 列
BOOL IsFull(Queue q) 后置条件: 若队列已满,则返回TRUE,否则返回FALSE。 void Append(Queue *q, T x) 后置条件:若队列已满,则指示Overflow,否则值为x的新元素进队列。 void Serve(Queue *q) 后置条件:若队列为空,则指示Underflow,否则从队列中删除队头元素。 void QueueFront(Queue q,T* x) 后置条件:若队列为空,则指示Underflow,否则在参数x中返回队头元素值。 }
第3章 堆 栈 和 队 列
第3章 堆 栈 和 队 列 队列的基本运算包括构造一个空队列,判定一个队列是 否为空队列,判定一个队列是否已满,在一个未满的队列中 插入一个新元素,从一个非空的队列中删除队头元素等。当 然我们还可以根据应用需要增加其它必要的队列运算,如求 队列的长度,清除一个队列,以及遍历一个队列等。队列的 抽象数据类型定义见ADT 3-2。
第3章 堆 栈 和 队 列 3.1.3 堆栈的链接表示 堆栈也可用单链表实现之,堆栈在链接存储方式下的实现 称为链式栈(linked stack),如图3-3所示。由于堆栈具有后进先 出特性,所以,栈顶指针 Top 指示的结点是 an-1 ,它是栈顶元 素,堆栈的栈底元素是单链表的尾结点。其结点类型与单链表 相同,
第3章 堆 栈 和 队 列