余腊中,数据结构c++版,第4章 栈、队列4
数据结构与算法(C语言篇)第4章 习题答案[2页]
习题答案1.填空题(1)非线性、一对多(2)前驱(3)叶结点(叶子结点)(4)度数(5)两(6)满二叉(7)从根结点到该结点之间的路径长度与该结点的权值的乘积(8)树中所有叶结点的带权路径长度之和(9)递增(10)平衡因子(11)B树的阶2.选择题(1)B (2)D (3)A (4)C (5)B (6)A (7)D (8)D3.思考题(1)如果i=1,则结点i无双亲,为根结点。
如果i>1,则结点i的双亲结点是结点i/2。
如果2i≤n,则结点i的左孩子是结点2i,否则结点i为叶结点。
如果2i+1≤n,则结点i的右孩子是结点2i+1,否则结点i无右孩子。
(2)非叶结点最多只有M个孩子,且M>2。
除根结点以外的非叶结点都有k个孩子和k-1个数据元素,k值满足[M/2]≤k≤M。
每一个叶结点都有k-1个数据元素,k值满足[M/2]≤k≤M。
所有叶结点都在同一层次。
所有分支结点的信息数据一致(n,A0,K1,A1,K2,A2……K n,A n),其中:K i(i=1,2……n)为关键字,且K i<K i+1(i=1,2……n-1);A i为指向孩子结点的指针,且指针A i−1指向子树中的所有结点均小于K i,A n所指子树中的所有结点的关键字均大于K n;n为关键字的个数([M/2]-1≤n≤M-1)。
(3)B+树是B树的升级版,区别在于叶结点在B+树的最底层(所有叶结点都在同一层),叶结点中存放索引值、指向记录的指针、指向下一个叶结点的指针。
叶结点按照关键字的大小,从小到大顺序链接。
分支结点不保存数据,只用来作索引,所有数据都保存在叶结点。
B*树是B+树的变体,B*树不同于B+树的是:其非根和非叶子结点上增加了指向兄弟结点的指针。
4.编程题(1)1//参数1为树的结点个数,参数2起始结点编号2btree_t *btree_create(int n, int i){3 btree_t *t;4 //使用malloc函数为结点申请内存空间5 t = (btree_t *)malloc(sizeof(btree_t));6 //将结点编号作为数据,保存至data中7 t->data = i;89 if(2 * i <= n){ //满足条件,说明结点有左孩子,编号为2i10 //递归调用,为左孩子的创建申请空间11 t->lchild = btree_create(n, 2 * i);12 }13 else{ //不满足条件,则没有左孩子14 t->lchild = NULL;15 }1617 if(2 * i + 1 <= n){ //满足条件,说明结点有右孩子,编号为2i+118 //递归调用,为右孩子的创建申请空间19 t->rchild = btree_create(n, 2 * i + 1);20 }21 else{ //不满足条件,则没有右孩子22 t->rchild = NULL;23 }2425 return t;26}。
数据结构(C语言版)_第4章 栈和队列
4.2 栈 4.2.1 栈的定义
栈(stack)是限定在表的一端进行插入或删除操 作的线性表。插入元素的操作称为入栈,删除元素的 操作称为出栈。在任何时候,都只有栈顶元素才能出 栈。换句话说,栈的修改是按先进后出、后进先出的 原则进行的,如图4-1所示。
图4-1 栈的示意图
因此,栈又称为先进后出(First In Last Out)表, 简称FILO表,或后进先出(Last In First Out)表,简称为 LIFO表。通常将允许进行插入或删除操作的一端称为栈顶 (top),被固定的另一端称为栈底(bottom)。不含数据元素的 栈称为空栈。
【拓展学习】两个栈共享同一存储空间。 在某些应用中,为了节省空间,可以让两个数据元素类型一致的 栈共享同一段一维数组空间。可以将两个栈的栈底设在存储空间 的两端,让两个栈分别向中间延伸。两个栈的栈顶变量分别为 top1、top2。只要整个存储空间未被占满,无论哪个栈的入栈都不 会发生上溢。只有两个栈的栈顶位置在中间相遇时(即 top1+1=top2)才发生上溢。因此,这种方法可以有效的提高存储 空间的利用率。我们把这种结构称为双栈,双栈如图4-7所示。
{ if (IsNull_Stack ( s ) ) return 0; /*栈空*/ else return (s->data[s->top] );
}
6. 置空栈操作 【算法4.6】置空栈 void Clear_Stack(Se_Stack *s) {
s->top=0; }
7. 求栈的长度 【算法4.7】求栈长 int StackLength(Se_Stack *s) {
第四章 栈和队列
本章要点
➢ 栈的定义和结构特点 ➢ 栈的顺序存储表示和基本操作的实现。 ➢ 栈的链式存储表示和基本操作的实现。 ➢ 队列的定义和结构特点 ➢ 队列的顺序存储表示和基本操作的实现。 ➢ 队列的链式存储表示和基本操作的实现。 ➢ 栈和队列的简单应用。
数据结构第四章的习题答案
数据结构第四章的习题答案数据结构第四章的习题答案在学习数据结构的过程中,习题是非常重要的一环。
通过解答习题,我们可以更好地理解和应用所学的知识。
在第四章中,我们学习了树和二叉树的相关概念和操作。
下面我将为大家提供一些第四章习题的答案,希望能帮助大家更好地掌握这一章节的内容。
1. 请给出树和二叉树的定义。
树是由n(n>=0)个结点构成的有限集合,其中有且仅有一个特定的结点称为根结点,其余的结点可以分为若干个互不相交的有限集合,每个集合本身又是一个树,称为根的子树。
二叉树是一种特殊的树结构,其中每个结点最多有两个子结点,分别称为左子结点和右子结点。
二叉树具有递归的定义,即每个结点的左子树和右子树都是二叉树。
2. 请给出树和二叉树的遍历方式。
树的遍历方式包括前序遍历、中序遍历和后序遍历。
前序遍历是先访问根结点,然后依次遍历左子树和右子树。
中序遍历是先遍历左子树,然后访问根结点,最后遍历右子树。
后序遍历是先遍历左子树和右子树,最后访问根结点。
二叉树的遍历方式包括前序遍历、中序遍历和后序遍历。
前序遍历是先访问根结点,然后依次遍历左子树和右子树。
中序遍历是先遍历左子树,然后访问根结点,最后遍历右子树。
后序遍历是先遍历左子树和右子树,最后访问根结点。
3. 给定一个二叉树的前序遍历序列和中序遍历序列,请构建该二叉树。
这个问题可以通过递归的方式解决。
首先,根据前序遍历序列的第一个结点确定根结点。
然后,在中序遍历序列中找到根结点的位置,该位置左边的结点为左子树的中序遍历序列,右边的结点为右子树的中序遍历序列。
接下来,分别对左子树和右子树进行递归构建。
4. 给定一个二叉树的中序遍历序列和后序遍历序列,请构建该二叉树。
和前面的问题类似,这个问题也可以通过递归的方式解决。
首先,根据后序遍历序列的最后一个结点确定根结点。
然后,在中序遍历序列中找到根结点的位置,该位置左边的结点为左子树的中序遍历序列,右边的结点为右子树的中序遍历序列。
数据结构(队列、栈、二叉树、图)
数据结构(队列、栈、二叉树、图)数据结构1.队列1.1 定义队列是一种先进先出(FIFO)的数据结构,类似于现实生活中排队的概念。
在队列中,元素只能从队尾入队,从队首出队。
1.2 常见操作- 入队(enQueue):将元素添加到队列的末尾。
- 出队(deQueue):从队列的头部移除元素,并返回移除的元素。
- 判空(isEmpty):检查队列是否为空。
- 获取队列长度(getSize):获取队列中元素的数量。
1.3 应用队列常用于模拟任务调度、消息传递和缓冲区等场景,例如操作系统的进程调度和网络通信中的消息队列等。
2.栈2.1 定义栈是一种后进先出(LIFO)的数据结构。
与队列不同,栈中的元素只能从栈顶进行操作。
2.2 常见操作- 入栈(push):将元素添加到栈顶。
- 出栈(pop):从栈顶移除一个元素,并返回移除的元素。
- 获取栈顶元素(peek):获取栈顶的元素,但不移除它。
- 判空(isEmpty):检查栈是否为空。
- 获取栈长度(getSize):获取栈中元素的数量。
2.3 应用栈常用于函数调用、计算表达式、深度优先搜索等场景,例如函数调用的栈帧、浏览器的回退功能等。
3.二叉树3.1 定义二叉树是一种有序树,其中每个节点最多有两个子节点。
通常将左子节点称为左子树,右子节点称为右子树。
3.2 基本概念- 根节点(Root):二叉树的顶层节点。
- 叶子节点(Leaf):没有子节点的节点。
- 父节点(Parent):有子节点的节点。
- 子节点(Child):父节点的直接下级节点。
- 兄弟节点(Sibling):具有相同父节点的节点。
3.3 基本操作- 创建二叉树(createTree):创建一个二叉树。
- 插入节点(insertNode):向二叉树中插入一个新节点。
- 删除节点(deleteNode):从二叉树中删除一个节点。
- 遍历二叉树(traverseTree):按照某种顺序访问二叉树的所有节点。
2021年数据结构C++版第4章.pptx
JYP
33
4.3.2 前序遍历
设T为一棵二叉树,T的前序遍历可递归定义为: (1) 若T为空,返回; (2) 访问T的根结点; (3) 前序遍历T的左子树; (4) 前序遍历T的右子树。
由此可得前序遍历的递归算法,如下一页所示。 对图4.10的二叉树,其输出是:+ * / A B C D,这正 好是表达式的前缀。
JYP
8
度为k的树称为k叉树。可以直接用含k个子女字 段的结点结构表示k叉树的结点,每个子女字段指 向相应的子女结点,但这会造成存储资源的很大浪 费。
引理4.1:如果用含k个子女字段的结点表示一棵 具有n(n≥1)个结点的k叉树,则n(k – 1) + 1个子 女字段的值是0。
证明:由于每个非0子女字段指向一个结点,且
显然,数组表示对完全树是最理想的,对于偏斜 树,空间利用率最低。
最坏情况下,深度为k的右偏斜树需要2k – 1个空 间单元,但其中只有k个用于存放数据。
JYP
24
2 链接表示 数组表示法对于很多二叉树空间浪费过大,而且
还存在顺序表示的固有缺点,即在树的中间插入和 删除结点需要移动大量其它结点。
在链接表示中,每个结点有三个字段:
JYP
17
引理4.3 [叶结点数与度为2的结点数之间的关系]:
对于任何非空二叉树,若n0为叶结点数,n2为度 为2的结点数,则n0 = n2 + 1。 证明:设n1为度为1的结点数,n为总结点数。由于 二叉树的结点度数最多为2,所以
n = n0 + n1 + n2
(4.1)
设B为分枝数,由于除了根结点以外,每个结点正 好由一个分枝引出,所以n = B + 1。所有分枝出自 度为1或2的结点,所以B = n1 + 2n2,从而有
数据结构c语言版
数据结构(C语言版)
(1) 输入:一个算法应该有零个、一个或多个输入。 (2) 有穷性:一个算法必须在执行有穷步骤之后正常结束, 而不能形成无穷循环。
(3) 确定性:算法中的每一条指令必须有确切的含义,不能 产生多义性。
(4) 可行性:算法中的每一个指令必须是切实可执行的,即 原则上可以通过已经实现的基本运算执行有限次来实现。
n+(n-1)+(n-2)+…+3+2+1=
n(n + 1) 2
数量级为O(n2)。算法中输出语句的频度为n,数量级为 O(n)。该算法的时间复杂度以if语句的执行频度来估算(忽略输 出部分),则记为O(n2)。算法还可能呈现的时间复杂度有指数阶 O(lbn)等。
数据结构(C语言版)
目录
第1章 绪论 第2章 线性表 第3章 栈和队列 第4章 串 第5章 数组 第6章 树 第7章 图 第8章 查找 第9章 排序 第10章 文件
数据结构(C语言版)
第1章 绪 论
1.1 数据结构的基本概念和术语 1.2 算法描述与分析 1.3 实习:常用算法实现及分析 习题1
数据结构(C语言版)
数据结构(C语言版)
(4) 关于数据存储结构的类型定义以及全局变量的说明等均 应在写算法之前进行说明。
下面的例子给出了书写算法的一般步骤。 例1.1 有n个整数,将它们按由大到小的顺序排序,并且输 出。 分析:n个数据的逻辑结构是线性表(a1,a2,a3,…,an);选用 一维数组作存储结构。每个数组元素有两个域:一个是数据的 序号域,一个是数据的值域。
1.2 算法描述与分析
1.2.1 什么是算法
在解决实际问题时,当确定了数据的逻辑结构和存储结构 之后,需进一步研究与之相关的一组操作(也称运算),主要有 插入、删除、排序、查找等。为了实现某种操作(如查找),常 常需要设计一种算法。算法(Algorithm)是对特定问题求解步骤 的一种描述,是指令的有限序列。描述算法需要一种语言,可 以是自然语言、数学语言或者是某种计算机语言。算法一般具 有下列5个重要特性:
栈和队列的顺序存储结构
栈和队列的顺序存储结构1. 栈的顺序存储结构栈是一种后进先出(Last In First Out,LIFO)的数据结构,它的顺序存储结构可以用数组实现。
我们可以将数组的最后一个位置作为栈顶,数组的第一个位置作为栈底。
当插入元素时,栈顶指针向上移动,指向新的元素;当删除元素时,栈顶指针向下移动,指向原来的栈顶元素。
2. 队列的顺序存储结构队列是一种先进先出(First In First Out,FIFO)的数据结构,它的顺序存储结构同样可以使用数组实现。
我们可以使用数组的第一个位置作为队头,数组的最后一个位置作为队尾。
当插入元素时,队尾指针向上移动,指向新的元素;当删除元素时,队头指针向下移动,指向原来的队头元素。
3. 栈和队列的应用场景栈和队列在计算机科学中有着广泛的应用。
栈常用于实现函数调用、递归算法、表达式求值等。
例如,在函数调用过程中,每次调用函数时,都会将函数的返回地址、局部变量等信息保存在栈中,当函数返回时,再从栈中弹出这些信息,恢复到调用函数之前的状态。
队列常用于实现任务调度、消息传递等。
例如,在操作系统中,可以使用队列来管理任务的执行顺序,保证任务按照先进先出的顺序得到执行。
4. 栈和队列的比较虽然栈和队列都是线性数据结构,但它们的特点和应用场景不同。
栈适用于后进先出的场景,例如需要倒序输出的情况;而队列适用于先进先出的场景,例如需要按照顺序处理的情况。
此外,栈和队列的操作复杂度也有所不同,栈的插入和删除操作都是O(1)的,而队列的插入和删除操作的复杂度均为O(1)。
总结:栈和队列是两种常见的数据结构,它们的顺序存储结构分别使用数组来实现。
栈适用于后进先出的场景,而队列适用于先进先出的场景。
栈和队列的应用场景广泛,可以用于函数调用、递归算法、任务调度等。
栈和队列的操作复杂度也有所不同,栈的插入和删除操作都是O(1)的,而队列的插入和删除操作的复杂度均为O(1)。
数据结构c语言版知识点总结
数据结构c语言版知识点总结数据结构是计算机科学中的一个重要概念,它指的是在计算机中存储和组织数据的方式以及操作数据的算法。
数据结构在计算机程序设计中扮演着至关重要的角色,C语言是一门广泛应用于数据结构编程中的语言,下面是一些数据结构C语言版的知识点总结。
1. 数组:是一种最基本的数据结构,它把数据放在一个连续的内存块中。
数组刚创建时,需要指定数组的大小,而不能改变。
对于数组,需要注意不要越界操作。
2. 链表:链表通过节点之间的指针来存储数据,每个节点都包含一个指向下一个节点的指针。
链表可以实现快速插入和删除操作,但访问数据时需要遍历整个链表。
3. 栈:栈是一种后进先出(LIFO)的数据结构。
栈中访问元素的顺序是从最后一个元素开始逐步向前访问。
栈的主要操作包括压栈(push)和弹栈(pop),分别在栈顶插入或删除元素。
4. 队列:队列是一种先进先出(FIFO)的数据结构。
队列中访问元素的顺序是从第一个元素开始逐步向后访问。
队列的主要操作包括入队(enqueue)和出队(dequeue),分别在队尾插入或删除元素。
5. 树:树是一种层级结构,其中每个节点都有一个父节点和零个或多个子节点。
树的节点通常包含一些数据以及指向其子节点的指针。
常见的树包括二叉树和二叉搜索树,它们分别有左右子节点和可排序的数据结构。
6. 图:图是由一组节点和它们之间的边组成的数据结构。
图可以是有向或无向的,它们包括顶点、边和权重。
图可以用于建立网页搜索引擎、社交网络等。
7. 堆:堆是一种特殊的树形数据结构,其中每个节点都有一个值,并且子节点的值小于或大于其父节点的值。
堆通常用于优先级队列实现等场景。
8. 哈希表:哈希表是一种基于哈希函数实现的数据结构,其中每个键(key)通过哈希函数映射到唯一的值(value)。
哈希表的查找、插入和删除操作都具有常数级别的时间复杂度,因此非常高效。
9. 字符串:字符串是由字符组成的序列,通常采用字符数组存储。
第4章栈及队列
4.1.5 栈的链式存储结构——链栈 1.链栈结构及数据类型
它是一种限制运算的链表,即规定链表中的扦入和删 除运算只能在链表开头进行。链栈结构见下图。
top 头
an
an-1
……
栈顶
图 3-5 链栈结构示意图
a1 ^
栈底
单链表的数据结构定义为: typedef struct node
{ elemtype data; //数据域 struct node *next; //指针域
3.出栈: POP(&S) 删除栈S中的栈顶元素,也称为”退栈”、 “删除”、 “弹出”。
4.取栈顶元素: GETTOP(S) 取栈S中栈顶元素。 5.判栈空: EMPTY(S) 判断栈S是否为空,若为空,返回值为1,否则返回值为0。
4.1.3 栈的抽象数据类型描述
ADT Stack {
Data: 含有n个元素a1,a2,a4,…,an,按LIFO规则存放,每个元素的类型都为 elemtype。 Operation: Void inistack(&s) //将栈S置为一个空栈(不含任何元素) Void Push(&s,x) //将元素X插入到栈S中,也称为 “入栈”、 “插 入”、 “压入”
{s->top[0]=-1; s->top[1]=m; }
(2)两个栈共享存储单元的进栈算法 int push(duseqstack *s, elemtype x, int i) //将元素x进入到以S为栈空间的第i个栈中 { if (s->top[0] ==s->top[1]-1) { printf(“overflow”); return (0);} if (i!=0 || i!=1) {printf(“栈参数出错“);return (0);} if(i= =0) //对0号栈进行操作 { s->top[0]++;s->stack[s->top[0]]=x;} else {s->top[1]--; s->stack[s->top[1]]=x;} return (1); }}
C语言数据结构进阶之栈和队列的实现
C语⾔数据结构进阶之栈和队列的实现⽬录栈的实现:⼀、栈的概念和性质⼆、栈的实现思路三、栈的相关变量内存布局图四、栈的初始化和销毁五、栈的接⼝实现:1.⼊栈2.出栈3.获取栈顶的数据4.获取栈的元素个数5.判断栈是否为空队列的实现:⼀、队列的概念和性质⼆、队列的实现思路三、队列相关变量的内存布局图四、队列的初始化和销毁五、队列的接⼝实现:1. ⼊数据2.出数据3.取队头数据4.取队尾数据5.获取队列元素个数6.判断队列是否为空总结栈的实现:⼀、栈的概念和性质栈(stack)⼜名堆栈,它是⼀种运算受限的线性表。
限定仅在固定的⼀端进⾏插⼊和删除操作的线性表。
这⼀端被称为栈顶,相对地,把另⼀端称为栈底。
栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插⼊操作叫做进栈/压栈/⼊栈,⼊数据在栈顶。
出栈:栈的删除操作叫做出栈。
出数据也在栈顶⼆、栈的实现思路栈的实现⼀般可以使⽤数组或者链表实现,相对⽽⾔数组的结构实现更优⼀些。
因为数组在尾上插⼊数据的代价⽐较⼩这⾥我们⽤顺序表结构来实现栈。
顺序表可以把使⽤的空间写成固定值,也可以构建动态开辟内存;但是如果写成固定的数组形式当存的数据满了就不能再使⽤了,所以下⾯我们实现的是动态开辟内存的形式。
所以我们先创建⼀个顺序表结构体类型,结构体类型中有指针,下标,容量。
指针:⽤来维护在堆上连续的⼀段空间,下标:表⽰数据存放到哪⼀个位置了,因为数据只能⼀个接着⼀个地存放,要有个下标来记录我数据放到哪⼀个位置了。
容量:与下标相⽐较,当下标与容量相等就表⽰空间存储满了,要进⾏扩容处理。
创建类型如下:typedef int STDataType; //对int类型重新起个名字叫DataType//创建⼀个栈结构体类型struct Stack{STDataType* a; //数据的指针int top; //栈顶int capacity; //记录开辟空间的最⼤下标处};//对顺序表类型struct Stack类型重新起个名字叫SLtypedef struct Stack ST;//当size 和 capacity相等时要进⾏扩容处理三、栈的相关变量内存布局图四、栈的初始化和销毁//初始化变量stvoid StackInit(ST* ps){ps->a = NULL;ps->capacity = 0;ps->top = 0;}//栈的销毁void StackDestroy(ST* ps){free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;}五、栈的接⼝实现:1.⼊栈//⼊栈void StackPush(ST* ps, STDataType x){assert(ps);//内存满了要扩容if (ps->capacity == ps->top){ps->capacity = ps->capacity > 0 ? ps->capacity * 2 : 2;STDataType* tmp =(STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity); if (tmp == NULL){perror("erron ");exit(-1);}ps->a = tmp;}//没有满就直接在后⾯⼊栈ps->a[ps->top] = x;ps->top++;}2.出栈//出栈,要注意栈不能为空void StackPop(ST* ps){assert(ps);//栈为空就不能再出栈了assert(ps->top >= 1);ps->top--;}3.获取栈顶的数据//返回栈顶的元素STDataType StackTop(ST* ps){assert(ps);//栈不能为空assert(ps->top >= 1);return ps->a[ps->top - 1];}4.获取栈的元素个数//获取栈的元素个数int StackSize(ST* ps){assert(ps);assert(ps->top >= 1);return ps->top - 1;}5.判断栈是否为空//判断栈是否为空bool StackEmpty(ST* ps){return ps->top == 0;}队列的实现:⼀、队列的概念和性质队列:只允许在⼀端进⾏插⼊数据操作,在另⼀端进⾏删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)的性质。
数据结构C语言版(第2版)严蔚敏人民邮电出版社课后习题答案之欧阳育创编
数据结构(C语言版)(第2版)课后习题答案李冬梅2015.3目录第1章绪论1第2章线性表6第3章栈和队列18第4章串、数组和广义表36第5章树和二叉树47第6章图60第7章查找75第8章排序89第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
在有些情况下,数据元素也称为元素、结点、记录等。
数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
例如,学生基本信息表中的学号、姓名、性别等都是数据项。
数据对象:是性质相同的数据元素的集合,是数据的一个子集。
例如:整数数据对象是集合N={0,±1,±2,…},字母字符数据对象是集合C={‘A’,‘B’,…,‘Z’,‘a’,‘b’,…,‘z’},学生基本信息表也可是一个数据对象。
数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。
换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。
逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。
因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。
存储结构:数据对象在计算机中的存储表示,也称为物理结构。
抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。
具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。
2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。
数据结构(第四章 栈和队列)
4.1 栈
栈的抽象数据类型
入栈示例
stacksize
base
base
base
base型
出栈示例
base
base
base
base
base
4.1 栈
栈的抽象数据类型
出、入栈示例
4.1 栈
栈的抽象数据类型
出、入栈示例
图4.1 栈(顺序栈)及其状态变化:{A, B, C, D} {入栈, 入栈, 出栈, 入栈, 入栈, 出栈, 出栈, 出栈}
4.1 栈
顺序栈
基于数组的顺序栈(经典实现)
(2)判读栈是否为空
public boolean isEmpty() //判断栈是否空,若空返回true { return this.top==-1; }
4.1 栈
顺序栈
基于数组的顺序栈(经典实现)
判读栈是否为满???
本实现采用与顺序表同样的处理:当 容量不够时,则将数组容量扩充一倍。
//栈顶元素下标
注意:element数组存储栈的数据元素;top表示当前 栈顶元素的下标。
4.1 栈
顺序栈
基于数组的顺序栈(经典实现)
顺序栈的实现从本质上讲,就是顺序线性表实现的 简化。惟一重要的是需要确定应该用数组的哪一端 表示栈顶:
一种选择是把数组的第0个位置作为栈顶。根据线性表的函 数,所有的插入(insert)和删除(remove)操作都在第0个位 置的元素上进行。由于这时每次push(insert)或者 pop(remove)操作都需要把当前栈中的所有元素在数组中 移动一个位置,因此效率不高。如果栈中有n个元素,则时 间代价为O(n)。 另一种选择是当栈中有n个元素时把位置n-1作栈顶。也就 是说,当向栈中压人元素时,把它们添加到线性表的表尾, 成员函数pop也是删除表尾元素。在这种情况下,每次 push或者pop操作的时间代价仅为O(1)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
0 1 2 3 4 5 6 7 8
a1 a2 a3
top top top 进栈:top加1 出栈:top减1
2014-8-22
栈空:top= -1
栈满:top= MAX_SIZE
中南大学@余腊生 14
数据结构与算法(C++版)
特殊线性表——栈
const int MaxStackSIZE=100; template <class T> class seqStack { public: seqStack ( ) ; ~seqStack ( ); void Push ( T x ); T Pop ( ); T GetTop ( ); bool Empty ( ); void ClearStack(); private: T data[MAX_SIZE]; int top; }
中南大学@余腊生 29
数据结构与算法(C++版)
两栈共享空间
两栈共享空间的实现——插入 操作接口:void Push(int i, T x) ;
1. 如果栈满,则抛出上溢异常; 2. 判断是插在栈1还是栈2; 2.1 若在栈1插入,则 2.1.1 top1加1; 2.1.2 在top1处填入x; 2.2 若在栈2插入,则 2.2.1 top2减1; 2.2.2 在top2处填入x;
时间复杂度?
2014-8-22 中南大学@余腊生 18
数据结构与算法(C++版)
顺序栈的实现——取栈顶元素
// return the value at the top of the stack template<class T> T seqStack<T>::GetTop (void) const { // if the stack is empty, terminate the program if (top == -1) {cerr << "Attempt to peek at an empty stack!" << endl; exit(1); } return data[top]; }
数据结构与算法(C++版)
特殊线性表——栈
栈的抽象数据类型定义
DestroyStack 前置条件:栈已存在 输入:无 功能:销毁栈 输出:无 后置条件:释放栈所占用的存储空间 Push 前置条件:栈已存在 输入:元素值x 功能:在栈顶插入一个元素x 输出:如果插入不成功,抛出异常 后置条件:如果插入成功,栈顶增加了一个元素
top1
什么时候栈1为空? 什么时候栈2为空?
2014-8-22
bj … … b2 b 1
top2
top1= -1 top2
top2= Stack_Size
27
中南大学@余腊生
数据结构与算法(C++版)
两栈共享空间
两栈共享空间
0 1 2 ……
S-1
a 1 a2 … … ai bj
top1 top2
什么时候栈1为空? 什么时候栈2为空?
2014-8-22
…
… b2 b1
top1= -1
top2= Stack_Size
28
什么时候栈满? top2= top1+1 中南大学@余腊生
数据结构与算法(C++版)
两栈共享空间
两 栈 共 享 空 间 类 的 声 明
2014-8-22
const int Stack_Size=100; template <class T> class BothStack { public: BothStack( ); ~BothStack( ); void Push(int i, T x); T Pop(int i); T GetTop(int i); bool Empty(int i); private: T data[Stack_Size]; int top1, top2; };
数据结构与算法(C++版)
第4章 特殊线性表—栈、队列
本章的基本内容是:
三种特殊的线性表——栈、队列、优先队列 从数据结构角度看,栈、队列和优先队列是操 作受限的线性表,他们的逻辑结构相同。
数据结构与算法(C++版)
特殊线性表——栈
栈的逻辑结构
栈:限定仅在一端进行插入和删除操作的线性表。
例: 羊肉串
2014-8-22 中南大学@余腊生 11
数据结构与算法(C++版)
特殊线性表——栈
栈的抽象数据类型定义
Empty 前置条件:栈已存在 输入:无 功能:判断栈是否为空 输出:如果栈为空,返回1,否则,返回0 后置条件:栈不变 endADT
2014-8-22
中南大学@余腊生
12
数据结构与算法(C++版)
特殊线性表——栈
栈的逻辑结构
例:有三个元素按a、b、c的次序依次进栈,且每个 元素只允许进一次栈,则可能的出栈序列有多少种?
情况2: 出栈序列:b
栈顶 栈顶 栈底
c a
出栈序列:b、c 出栈序列: b、 c、a
注意:栈只是对表插入和删除操作的位置进行了限 中南大学@余腊生 2014-8-22 8 制,并没有限定插入和删除操作进行的时间。
中南大学@余腊生 15
顺 序 栈 类 的 声 明
2014-8-22
数据结构与算法(C++版)
// initialize stack top.
template<class T> seqStack <T>:: seqStack (void) : top(-1) {}
2014-8-22
中南大学@余腊生
16
中南大学@余腊生
22
数据结构与算法(C++版)
特殊线性表——栈
两栈共享空间
在一个程序中需要同时使用具有相同数据类型的两个栈, 如何顺序存储这两个栈? 解决方案1:
直接解决:为每个栈开辟一个数组空间。 会出现什么问题?如何解决? 解决方案2: 顺序栈单向延伸——使用一个数组来存储两个栈
2014-8-22 中南大学@余腊生 23
中南大学@余腊生 17
时间复杂度?
2014-8-22
数据结构与算法(C++版)
顺序栈的实现——出栈
// pop the stack and return the top element
template<class T> T seqStack<T>::Pop (void) { T temp; // if stack is empty, terminate the program if (top == -1) {cerr << "Attempt to pop an empty stack!" << endl; exit(1); } temp = data[top]; // record the top element top--; return temp; }
情况1:
栈顶
栈顶
栈顶 栈底
2014-8-22
c b a
中南大学@余腊生 5
数据结构与算法(C++版)
特殊线性表——栈
栈的逻辑结构
例:有三个元素按a、b、c的次序依次进栈,且每个 元素只允许进一次栈,则可能的出栈序列有多少种? 情况1: 出栈序列:c
栈顶 栈顶 栈顶 栈底
2014-8-22
c b a
数据结构与算法(C++版)
特殊线性表——栈
两栈共享空间
两栈共享空间:使用一个数组来存储两个栈,让一个 栈的栈底为该数组的始端,另一个栈的栈底为该数组 的末端,两个栈从各自的端点向中间延伸。
2014-8-22
中南大学@余腊生
24
数据结构与算法(C++版)
两栈共享空间
两栈共享空间
0 1 2 ……
S-1
数据结构与算法(C++版)
顺序栈的实现——入栈
// push item on the the stack
template<class T> void seqStack<T>::Push (const T& item) { // if stack is full, terminate the program if (top == MaxStackSize-1) { cerr << "Stack overflow!" << endl; exit(1); } // increment top and copy item to stacklist top++; data[top] = item; }
数据结构与算法(C++版)
特殊线性表——栈
栈的抽象数据类型定义
ADT Stack Data 栈中元素具有相同类型及后进先出特性, 相邻元素具有前驱和后继关系 Operation InitStack 前置条件:栈不存在 输入:无 功能:栈的初始化 输出:无 后置条件:构造一个空栈
2014-8-22 中南大学@余腊生 9
a 1 a2 … ai
栈1底
bj … … b2 b 1
top2
栈2底
top1
栈1的底固定在下标为0的一端; 栈2的底固定在下标为StackSize-1的一端。 top1和top2分别为栈1和栈2的栈顶指针; Stack_Size为整个数组空间的大小(图中用S表示);
2014-8-22 中南大学@余腊生 25
2014-8-22
中南大学@余腊生
10
数据结构与算法(C++版)
特殊线性表——栈
栈的抽象数据类型定义
Pop 前置条件:栈已存在 输入:无 功能:删除栈顶元素 输出:如果删除成功,返回被删元素值,否则,抛出异常 后置条件:如果删除成功,栈减少了一个元素 GetTop 前置条件:栈已存在 输入:无 功能:读取当前的栈顶元素 输出:若栈不空,返回当前的栈顶元素值 后置条件:栈不变