数据结构学习笔记(一):Heap
来源:互联网 发布:unity3d 改变模型动画 编辑:程序博客网 时间:2024/06/01 08:27
数据结构学习笔记(一):Heap
本文提要:
- 什么是Heap
- Heap的分类和特性
- Heap的实现方法
- Heap的主要操作
- Heap在Java中的实现
- 总结
什么是Heap?
Heap即为堆。它和stack(栈)一样,在计算机科学中都有两种完全不同的含义:在Operating System中,它是内存中的一块区域,而在数据结构中,它是一种树形的数据结构。这里所说的树形结构并不是指用二叉树来实现。事实上,heap通常用数组来实现,只是在视觉上表示成一个二叉树,这样会使得该结构更清晰,也更容易让人理解。例如下图就是heap的一个例子:
Heap的分类和特性
Heap主要分为最大堆和最小堆。最大堆所有节点的值都比其子节点的值要大,而最小堆则相反,所有节点的值都要比其子节点的值要小。
最大堆(图片来自www.tutorialspoint.com):
最小堆(图片来自www.tutorialspoint.com):
Heap的实现方法
Heap可以通过数组来实现。以下图为例:
图中所示是一个最小堆,root的值(即最小值)为10。我们按照从上往下,从左往右的顺序将所有节点的值放入一个数组中,即可得到一个值为[10, 14, 19, 26, 31, 42, 27, 44, 35, 33]的数组。假设数组名称为heap,那么可以发现,节点i(即heap[i])的左子节点的index值为2i+1,右子节点的index值为2i+2。同理也可以得到节点i的父节点为(i-1)/2。
注:上面所说的index是从0开始计算的,如果你将root的index标记为1(即index从1开始),那么左右子节点的index值则为2i和2i+1,而父节点的index值为i/2。
Heap的主要操作
Heap的主要操作有:
- Push
- Pop
- Remove
接下来说说这三种操作的具体实现以及时间复杂度,均以下图为例:
Push
Push即为将一个新的节点压入堆中。通常的做法是先将节点直接至于最后(如果用数组实现也就是数组的末尾),在通过不断地与父节点进行swap操作来将其置于正确的位置。Push的时间复杂度是O(log n)。
例如,如果我们想将12插入heap中,那么应该怎么做呢?
首先,将12插入heap末尾,即成为31的右子节点。将12与31进行比较,发现12比较小,因此将其与31进行调换。这时,12成为了14的右子节点,也是31和33的父节点。之后再将12与其父节点14进行比较,发现12更小,那么继续将12与14调换。然后再将12与父节点10进行比较,发现10更小,push操作结束。
Pop
Pop是将堆顶节点弹出。通常的做法是将堆顶节点与末尾节点对调,取出末尾节点后将新的堆顶节点与其子节点不断比较和对调,直到将其置于正确的位置中。由于过程与push类似,这里就不举例了。Pop的时间复杂度也是O(log n)。
Remove
Remove即移除某一节点(不一定是顶节点)。通常做法是先搜寻出目标节点,再将其与末尾节点对调,并将末尾节点置于正确的位置。Remove的时间复杂度主要取决于搜寻部分,如果是简单的对所有节点进行一边比较,那么时间复杂度为O(n);如果另外建立一个哈希表来存储节点值以及其位置信息(通常是指向目标节点的指针),那么搜寻部分的时间复杂度将会降到O(1),而总的时间复杂度也会因此降为O(log n),这也就是所谓的HashHeap。
Heap在Java中的实现
在Java中有一个名为PriorityQueue的class,实现的就是heap的数据结构。它有几个比较重要的method需要我们记住:
add()
即上文所说的push操作。
peek()
返回堆顶节点,但不将其从堆中取出。
poll()
返回堆顶节点,同时将其从堆中取出(即上文所说的pop操作)。
remove()
即上文所说的remove操作,时间复杂度为O(n)。
size()
返回堆中节点数量。
总结
Heap是一种常用的数据结构,主要用在需要快速得到某些元素中最大或最小值的情况下。
- 数据结构学习笔记(一):Heap
- 数据结构学习笔记(一)
- 学习笔记:数据结构(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记 (一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记(一)
- 数据结构学习笔记一
- 数据结构学习笔记(一)
- 数据结构学习笔记一
- 学习-数据结构-heap
- 数据结构学习笔记(一)基础知识
- 面向对象-第一个代码模型
- java String
- linux tftp服务器搭建与测试
- 大白话Docker入门(一)
- JAVA将逗号连接的字符串转换为Map
- 数据结构学习笔记(一):Heap
- JAVASE基础-day11(开发工具&常见对象)
- Android中微信抢红包助手的实现
- 伸缩布局之-侧轴的对齐方式
- 并发编程的挑战(一)
- 让Thrift支持双向通信
- 解决:The project cannot be built until build path
- Tinker接入小白教程
- win10快捷键大全 win10常用快捷键