第3章 表 栈 和 队列
来源:互联网 发布:数据反馈的拳击手套 编辑:程序博客网 时间:2024/05/22 04:55
第3章 表 栈 和 队列
每一种有意义的程序都将显示的至少使用一种这样的数据结构,而栈总是要被间接的使用到
3.1 抽象数据类型
抽象数据类型(ADT)是带有一组操作的一些对象的集合,抽象数据类型是数学的抽象,在ADT的定义中没有提到关于这组操作时如何实现的任何解释。
3.2 表ADT
我们将处理形如A0 A1 A2 .... AN-1 的一般的表,我们说这个表的大小为N我们将大小为0的表称为空表
我们说Ai 后继Ai-1或继 Ai-1之后并称Ai-1前驱Ai不定义A0的前驱元和An-1的后继元
3.2.1 表的简单数组实现
对表的所有操作可以用数组来实现
将旧数组赋值给新数组就可以实现数组扩容
插入和删除潜藏着昂贵的开销,主要是看插入和删除在什么地方(线性开销0(N-i))
3.2.2 简单链表
为了避免插入和删除的线性开销,我们需要保证表可以不连续存储,所有可以采用链表
链表有一系列节点组成,这些节点不必在内存中相连,每一个节点均含有表元素和到包含该元素的后继元的节点的链
查找一个元素需要花费O(i)的时间,
联表示适合插入和删除,不需要移动多余的项
3.3 JAVA Collection API中的表
3.3.1 Collection接口
集合collection的概念在Collection接口中得到抽象,它存储一组类型相同的对象,
Collection接口扩展了Iterable(java.lang)接口,实现Iterable的那些类可以拥有增强for循环
3.3.2 Iterator接口
实现Iterator(java.util)接口的思路是,通过iterator方法,每一个集合均可创建并返回给客户一个实现Iterator接口的对象,并将当前位置的概念在对象中存储下来
Iterator的remove()的主要优点在于Collection的remove()方法必须首先找到要被删除的项,如果知道要删除的项的位置,那么删除开销会小很多
当直接使用Iterator遍历时,重要的是要记住一个基本法则, 如果对正在被迭代的集合进行结构上的改变,那么迭代器就不在合法,这也是更喜欢使用迭代器remove()方法的原因
3.3.3 List接口ArrayList和LinkedList类
ArrayList的优点在于,对get() set()方法的调用花费常数时间,其缺点是新项的插入和删除代价昂贵,除非变动的是最后一个元素
LinkedList的优点在于插入和删除开销都很小队已知位置,对添加和删除都是常数时间,缺点是 它不易做索引,因此对get的调用时昂贵的,除非调用非常靠近表的端点(如果对表的调用靠近表的尾端,那么搜索也可以从尾部开始)
如果我们通过向表的前段添加一些项来构造一个List
对于LinkedList它运行时间是O(N)对于ArrayList它的运行时间是O(N2)
如果我们是对集合进行遍历
对于LinkedList它运行时间是O(N2)对于ArrayList它的运行时间是O(N)
对于搜索而言,ArrayList和LinkedList都是低效的,对Collection的contains()和remove()两个方法均花费线性时间
trimTosize()方法将容量设置为集合的长度,操作,ArrayList调用该方法可以避免浪费空间
扩容代码: int newCapacity = (oldCapacity * 3)/2 + 1;
3.3.4 例子 remove()方法对LinkedList类的使用
eg. 假如一个表包含 6,5,1,4,2需要将表中的偶数都删除
1. 显然对于ArrayList这几乎是一个失败的策略(任意地方删除都很昂贵)
2. LinkedList暴漏了两个问题
(1)get()调用效率不高
(2)remove()方法效率同样很低
3. 因此我们应该使用一个迭代器一步一步遍历该表,但是我们使用的是Collection的remove()方法来删除一个偶数值,这不是高效的操作,(因为remove()方法必须再次搜索该项,它花费线性时间)但更糟的是程序会产生异常
4 在迭代器找到一个偶数值时,我们可以使用该迭代器来删除这个值(对于迭代器而言,只用花费常数时间)
public static void removeEvenver(List<Integer> 1st) {
Interator<Integer> itr = 1st.iterator();
while (itr.hasNext()) {
if(ist.next() % 2 == 0) {
itr.remove() ;
}
}
}
3.3.5 关于ListIterator接口
ListIterator扩展了List和Iterator的功能,previous() hasPrevious()使得表可以从后面想前遍历
3.4 ArrayList类的实现
为了和类库ArrayList类区别 我们编写的类叫做MyArrayList
实现MyArrayList包括的细节
1. MyArrayList将保持基础数组,数组的容量,及当前项
2. MyArrayList提供一种机制来改变数组的容量,允许GC回收老数组
3. MyArrayList 提供get()和set()的实现
4. MyArrayList 提供基本的方法 size,isEmpty,clear还提供remove以及两个不同版本的add如果数组的大小容量都相同,那么这两个add()将增加容量
5. MyArrayList将提供一个实现Iterator接口的类,
3.4.2 迭代器java嵌套类和内部类
3.5 LinkedList类的实现
MyLinkedList 设计要求
1. MyLinkedList类本身,它包含到两端的链,表的大小及一些方法
2. Node类,它可以是一个私有的嵌套类,一个节点包含数据以及前一个节点和下一个节点的链,还有一些构造方法
3. LinkedListIterator类,该类抽象了位置概念,是一个私有类,并实现接口Iterator
3.6 栈ADT
3.6.1 栈模型
栈是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈的顶(top)
当栈为空的时候进行pop()和top()一般别认为栈ADT中的一个错误,
当栈满时,运行push()是一个实现限制,并不是错误。
栈有时又叫做LIFO(后进先出)表
3.6.2 栈实现
由于栈是一个表,因此可以使用任何实现表的方法来实现栈,因为栈的操作时常数时间操作,
我们给出两种方法来实现
1. 栈的链表实现
使用单链表,通过在表的顶端插入来实现push(),通过删除表顶端元素来实现pop()
top()操作只是获得顶端元素并返回它的值
2. 栈的数组实现方法
模仿了ArrayList的add()操作
这些操作不仅以常数时间运行,最现代化的计算机把栈操作作为它的指令的一部分,栈有可能成为数组之后的最基本的数据结构了
3.6.3应用
1. 平衡符号
编译器检查程序语法错误,但常常由于缺少一个符号,引起编译成列出很多错误提示,但是并没有找到真正的错误
2 后缀表达式
4.99 1.06*5.99 + 6.99 1.06* 这种记法叫做后贼或者逆波兰
3. 中缀到后缀的转换
可以用栈将一个标准形式的表达式(或叫作中缀的表达式转换成后缀)
4. 方法调用
当调用一个新的方法时,主调例程的所有局部变量需要由系统存储起来,否则被调用的新方法将会重写由主调例程的变量所使用的内存,不仅如此,主调例程的当前位置也要储存,这些变量一般由编译器指派给机器的寄存器
当存在方法调用的时候,需要储存的所有重要信息,诸如寄存器的值(对应变量的名字)返回地址(可以从程序的计数器中得到,一般是在一个寄存器中)等都要以抽象的形式存在堆的顶部
递归的所有工作都可以由一个栈来完成,而这正是实现递归的每一种程序设计语言中实际发生的事情。所存储的信息或称为活动记录,或叫作栈帧。
3.7队列ADT
队列也是表,使用队列时,插入在一段进行而删除在另一端进行
3.7.1 队列模型
队列的基本操作时入队enqueue,它是在表的末端(队尾)插入一个元素,和出队,它是删除dequeue并返回在表的开头(队头)的元素
3.7.2 队列的数组实现
对于队列而言任何的表的实现都是合法的,队列通常不是很大
- 第3章 表、栈和队列
- 第3章 表 栈 和 队列
- 第3章 表、栈和队列
- 数据结构 第3章 栈和队列
- 第3章 栈和队列
- 第3章栈和队列
- 第3章栈和队列
- 第3章 栈、队列和数组
- 第3章 表、栈、和队列 课后练习
- 第3章——表、栈和队列
- 数据结构与算法分析(第3版)练习题-第3章-表、栈和队列
- 第3章 栈和队列——循环队列的元素的插入和删除
- 第3章《栈和队列》 思维导图
- 数据结构(第3章: 栈和队列)
- 数据结构笔记整理第3章:栈和队列
- 第3章 栈和队列的应用
- 第3章 栈和队列综合习题(leetcode+vjudge)
- 第04章 栈和队列
- Phoenix资源列表
- 287. Find the Duplicate Number
- mysql基本操作一览
- Highway Network & ResNet & ICCV 2015 笔记参考
- 开发一个基于Canvas的网页绘图应用程序
- 第3章 表 栈 和 队列
- “正交阵”与“特征值和特征向量”
- Java开发中的23种设计模式详解(转)
- 父页面调用easyui datagrid
- 2016年7月最新Windows市场份额
- Android Volley,使用Volley加载网络图片
- 114. Flatten Binary Tree to Linked List
- spring 事物控制---多数据源与 atomikos 分布式事务配置(接之前未完成的部分)
- 卡特兰数