算法引论数据结构--堆的简介与实现
来源:互联网 发布:用什么软件做蹭饭地图 编辑:程序博客网 时间:2024/06/07 01:29
算法引论 数据结构—堆简介及部分代码实现
堆是一种二叉树,其所有节点的关键字均满足如下性质:
任意一个节点的关键字都大于或等于其任意一个子节点的关键字。
由传递性原理可知,堆得上述性质说明了堆上任意一个节点的关键字都大于或等于其“后代“的所有关键字。堆在实现优先级队列的时候很有用,优先级队列是一种抽象数据类型,通过如下两个操作定义:
Insert(x):把关键字x插入该数据结构
Remove():从该数据结构中删除最大的关键字。
堆可用显示结构表示,也可用隐式结构表示。我们要保证堆的平衡,我们是用隐式结构来实现。我们假设数组A[1…n]是其隐式表示,其中k可能是堆包含的元素的上限(如果上限不能确定,我们只能用链表)。把堆中目前元素的个数记做n,也就是说,我们只关心A[1..n].下面,我们就来描述如何用堆来实现对元素的高效插入和删除。
从Remove操作入手。根据堆的性质,堆中关键字最大的节点是根节点A[1],因此Remove总是删除根节点。我们首先取叶子节点A[n],把它移到根节点A[1]处,然后删除叶子节点A[n],n要自减1.我们记新的A[1]的值为x,得到的是两个独立的堆以及它们上方的值,但该值未必满足堆的性质。(此时只有从根节点到原先x所在节点的路径上的所有节点的值都是x,堆的性质才可能满足)。为了满足堆的性质,我们现在把x向树的下方移动,直到它到达某棵子树,在这棵子树中x是最大值。移动的方式则是通过比较x和它的两个子节点,比如(A[2],A[3]),如果x不是这里最大的值,那么我们把x与A[2],A[3]中最大的值作为交换,假设这里是A[3]最大,那么我们A[2]以及它的子树仍然满足堆的性质,我们只需考虑A[3]及它的子树是否满足堆的性质。我们用同样的方式对该子树进行同样的处理,假设目前处理到了第i步,A[j]中存放着x,按照上述方法比较x与它的子节点A[2j]和A[2j+1](如果存在的话),如果x不是这三个数中的最大值,则如上进行交换。当x为某棵子树的节点的最大值,或者x到达叶子节点时,算法终止。删除堆中元素的最大比较次数约为2lgn,刚好是树的两倍高。
下面是我们的实现代码
`
public class HeapDemo {
private int[] array;
private int size;
public HeapDemo(int k) { array = new int[k+1]; //下标0是不用的 size = 1 ; //数组元素个数,也可以当成数组下标。 } private void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } public void remove() throws Exception{ if (size == 0) throw new Exception("heap empty"); array[1] = array[size]; size--; int parent = 1, child = 2; while (child <= size-1) { if (array[child] < array[child+1]) child++; if (array[child] > array[parent]) { swap(array, child, parent); parent = child; child *= 2; } else child = size; //终止循环 } } } `
Insert操作相似,先让n自增1,然后在叶子节点A[n]插入新值,接着比较这个新的叶子节点及其父节点的值,如果大于父节点的值,则交换这两个节点。这样一来,这个新值就是其子树的节点值最大的(因为原来的父节点的值最大,而它的值大于父节点的值)。通过归纳,可以假设以Aj为根节点的树满足堆的性质,且如果去掉这棵树,剩下的部分也满足堆的性质。由此继续执行,将新节点继续往树的上方移动,直到其值不比父节点的大(或者直到它已经到了根节点的位置)。至此,得到的这棵树就完全满足堆的性质。在堆中插入元素的最大比较次数约为lgn,恰好是树的高度。
在上述代码的基础上继续实现:
` public void insert(int x) throws Exception{ if (size == array.length) throw new Exception("heap full"); size++; array[size] = x; int child = size, parent = size/2; // while (parent >= 1) { if (array[child] > array[parent]) { swap(array, child, parent); child = parent; parent /= 2; } else parent = 0; } }`
- 算法引论数据结构--堆的简介与实现
- 《数据结构与算法分析》引论:选择问题实现
- ReviewForJob(1)数据结构与算法分析引论
- 数据结构与算法分析 | 01 | 引论
- 数据结构与算法-引论-练习1.1
- 数据结构与算法分析-二叉堆的实现
- 【数据结构与算法】左偏树(堆)的实现
- 【数据结构与算法】【排序】堆排序的代码实现
- 算法与数据结构-堆的基本操作C语言实现
- 算法与数据结构-堆的基本操作C语言实现
- 数据结构与算法-堆、基于堆实现的优先队列、堆排序
- 数据结构与算法分析再读之引论和算法分析
- 算法与数据结构 - 堆
- 《数据结构与算法分析--c语言描述》之第一章:引论
- 数据结构与算法分析(读书笔记):1.引论
- 数据结构:堆排序算法的实现
- 数据结构与算法(C#实现)---二叉堆(数组实现)
- 数据结构与算法:堆与堆排序
- Cocos2d-x项目创建之 静态库生成
- MyISAM与InnoDB区别
- 擅长排列的小明 II
- 神经网络(上):神经元与感知机
- 最小费用最大流,未过,先存着
- 算法引论数据结构--堆的简介与实现
- Android 开发—— 小工具,大效率
- 条款18:让接口容易被正确使用,不容易被误用
- 教你如何免费下载浏览器上收费的音乐和视频
- 弹幕刷屏之术——Android无时间线弹幕实现
- 宏求余
- 杭电oj1009(贪心算法)
- matplotlib绘图、图片处理、绘制文字
- 正则表达式