二叉堆

数据结构(Java语言)——BinaryHeap简单实现

ぐ巨炮叔叔 提交于 2019-12-17 03:35:25
优先队列priority queue是同意至少下列两种操作的数据结构:insert插入以及deleteMin(删除最小者),它的工作是找出,返回并删除优先队列中最小的元素。insert操作等价于enqueue入队。而deleteMin则是dequeue出队在优先队列中的等价操作。 一种实现优先队列的方法是使用二叉堆binary heap,它的使用对于优先队列的实现相当普遍,以至于当堆heap这个词不加修饰地用在优先队列的上下文中时,一般都是指数据结构的这样的实现。在本节。我们把二叉堆仅仅叫做堆。像二叉查找树一样,堆也有两个性质,即结构性和堆序性。恰似AVL树,对堆的一次操作可能破坏这两个性质中的一个。因此,堆得操作必须到堆得全部性质都被满足时才干终止。其实这并不难做到。 堆是一棵被全然填满的二叉树,有可能的例外是在底层。底层上的元素从左到右填入。这种树称为全然二叉树。easy证明。一棵高为h的全然二叉树有2^h到2^(h+1)-1个节点。 这意味着全然二叉树的高是logN向下取整,显然它是O(logN)。 一个重要的观察发现,由于全然二叉树这么有规律,所以它能够用一个数组表示而不须要使用链。对于数组中任一位置i上的元素。其左儿子在位置2i上,右儿子在左儿子后的单元(2i+1)中,它的父亲则在位置i/2中。因此,这里不仅不须要链。并且遍历该树所须要的操作极简单

浅谈算法和数据结构: 五 优先级队列与堆排序

邮差的信 提交于 2019-12-16 22:29:14
在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象。最简单的一个例子就是,在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话。 在这种情况下,我们的数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue) 。 本文首先介绍优先级队列的定义,有序和无序数组以及堆数据结构实现优先级队列,最后介绍了基于优先级队列的堆排序(Heap Sort) 一 定义 优先级队列和通常的栈和队列一样,只不过里面的每一个元素都有一个”优先级”,在处理的时候,首先处理优先级最高的。如果两个元素具有相同的优先级,则按照他们插入到队列中的先后顺序处理。 优先级队列可以通过链表,数组,堆或者其他数据结构实现。 二 实现 数组 最简单的优先级队列可以通过有序或者无序数组来实现,当要获取最大值的时候,对数组进行查找返回即可。代码实现起来也比较简单,这里就不列出来了。 如上图: · 如果使用无序数组,那么每一次插入的时候,直接在数组末尾插入即可,时间复杂度为O(1),但是如果要获取最大值,或者最小值返回的话,则需要进行查找,这时时间复杂度为O(n)。 · 如果使用有序数组,那么每一次插入的时候,通过插入排序将元素放到正确的位置,时间复杂度为O(n)

关于PriorityQueue 二叉堆的问题

こ雲淡風輕ζ 提交于 2019-12-14 21:50:09
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 场景:最近在研究java中的队列,当研究到优先队列的时候去读 PriorityQueue的源码的时候发现一种数据结构,我数据结构这块基本上上是空白,所以让我晦涩难懂啊,于是我查阅了大量资料以及手动书写程序代码测试后,终于搞懂了这种数据结构交二叉堆,其实堆就是一个数组,只不过用数组的结构来存储一颗近似二叉树 呵呵,闲话少叙,看我上代码 有关资料: 堆(数据结构) 二叉堆 堆排序 看我演示代码: package test.queue; import java.util.PriorityQueue; import java.util.Queue; /** * Author: skyline{http://my.oschina.net/skyline520} * Created: 13-6-1 上午8:07 */ public class TestQueue { public void printPriorityQueue(){ Queue<Integer> priorityQueue = new PriorityQueue<Integer>(); priorityQueue.add(1); priorityQueue.add(9); priorityQueue.add(3); priorityQueue.add(8)

海量数据处理专题4——堆

被刻印的时光 ゝ 提交于 2019-12-08 18:45:04
【什么是堆】 概念:堆是一种特殊的二叉树,具备以下两种性质 1)每个节点的值都大于(或者都小于,称为最小堆)其子节点的值 2)树是完全平衡的,并且最后一层的树叶都在最左边 这样就定义了一个最大堆。如下图用一个数组来表示堆: 那么下面介绍二叉堆:二叉堆是一种完全二叉树,其任意子树的左右节点(如果有的话)的键值一定比根节点大,上图其实就是一个二叉堆。 你一定发觉了,最小的一个元素就是数组第一个元素,那么二叉堆这种有序队列如何入队呢?看图: 假设要在这个二叉堆里入队一个单元,键值为2,那只需在数组末尾加入这个元素,然后尽可能把这个元素往上挪,直到挪不动,经过了这种复杂度为Ο(logn)的操作,二叉堆还是二叉堆。 那如何出队呢?也不难,看图: 出队一定是出数组的第一个元素,这么来第一个元素以前的位置就成了空位,我们需要把这个空位挪至叶子节点,然后把数组最后一个元素插入这个空位,把这个“空位”尽量往上挪。这种操作的复杂度也是Ο(logn)。 【适用范围】 海量数据前n大,并且n比较小,堆可以放入内存 【基本原理及要点】 最大堆求前n小,最小堆求前n大。方法,比如求前n小,我们比较当前元素与最大堆里的最大元素,如果它小于最大元素,则应该替换那个最大元 素。这样最后得到的n个元素就是最小的n个。适合大数据量,求前n小,n的大小比较小的情况,这样可以扫描一遍即可得到所有的前n元素,效率很高。

海量数据处理专题(五)——堆

蓝咒 提交于 2019-12-08 18:44:18
转: http://blog.redfox66.com/post/mass-data-topic-5-heap.aspx 【什么是堆】 概念:堆是一种特殊的二叉树,具备以下两种性质 1)每个节点的值都大于(或者都小于,称为最小堆)其子节点的值 2)树是完全平衡的,并且最后一层的树叶都在最左边 这样就定义了一个最大堆。如下图用一个数组来表示堆: 那么下面介绍二叉堆:二叉堆是一种完全二叉树,其任意子树的左右节点(如果有的话)的键值一定比根节点大,上图其实就是一个二叉堆。 你一定发觉了,最小的一个元素就是数组第一个元素,那么二叉堆这种有序队列如何入队呢?看图: 假设要在这个二叉堆里入队一个单元,键值为2,那只需在数组末尾加入这个元素,然后尽可能把这个元素往上挪,直到挪不动,经过了这种复杂度为Ο(logn)的操作,二叉堆还是二叉堆。 那如何出队呢?也不难,看图: 出队一定是出数组的第一个元素,这么来第一个元素以前的位置就成了空位,我们需要把这个空位挪至叶子节点,然后把数组最后一个元素插入这个空位,把这个“空位”尽量往上挪。这种操作的复杂度也是Ο(logn)。 【适用范围】 海量数据前n大,并且n比较小,堆可以放入内存 【基本原理及要点】 最大堆求前n小,最小堆求前n大。方法,比如求前n小,我们比较当前元素与最大堆里的最大元素,如果它小于最大元素,则应该替换那个最大元 素

优先队列的基本数据结构(2)

爱⌒轻易说出口 提交于 2019-12-07 16:15:00
摘要:本次提供另外一些优先队列的基本操作 【1】 对二叉堆进行下滤,就是让某个元素降至到使得它符合二叉堆优先结构的节点. void PerLocateDown(Heap H, int i) //对二叉堆进行下滤 { int child; int FirstElement = H->Element[i]; for (;i* 2 <= H->heapsize; i = child ) { //for循环 一直到满足堆序或者到底层 //获取最小儿子 child = i* 2 ; if (child != H->heapsize && H->Element[child+ 1 ]<H->Element[child] ) child++; if (FirstElement > H->Element[child]) { //不满足堆序,交换节点 H->Element[i] = H->Element[child]; } else break ; //满足堆序 } H->Element[i] = FirstElement; } 【2】对二叉堆进行上滤,使得它上升到某个符合堆序的位置; void PerLocateUp(Heap H, int i ) { //将一个元素【i】上滤 int LastElement = H->Element[i]; for (; LastElement < H-

二叉堆(三)之 Java的实现

大憨熊 提交于 2019-12-04 01:49:54
博客园博主 skywang123456 (以下简称s博主)是一个大牛级的人物,相信很多程序员都拜读过他的博客,我也不例外,并且受益匪浅。但是对于文章 二叉堆(三)之 Java的实现 我有一些疑惑,写在这里,供有缘人参考。对于而二叉堆的插入,是一个较为简单的方法,这里没有什么问题。但是而二叉堆的删除确是一个稍微复杂一点的操作,事实上,我第一次看这篇博文的时候就感觉有些恍惚不清。一般来说,而二叉堆的删除分为删除堆顶和查找型删除。堆顶删除可以由查找型删除实现,故名思意,直接删除堆顶的数据即可,在二叉堆的实际应用中被广泛使用。而查找型删除首先要查到给定参数的位置,然后删除该元素。而我要指出的问题是博主s使用删除堆顶的代码来代替了查找型删除的代码,而这两个我会举例是不同的。 先来看博主s的删除代码 public int remove(T data) { // 如果"堆"已空,则返回-1 if(mHeap.isEmpty() == true) return -1; // 获取data在数组中的索引 int index = mHeap.indexOf(data); if (index==-1) return -1; int size = mHeap.size(); mHeap.set(index, mHeap.get(size-1));// 用最后元素填补 mHeap.remove(size -

优先队列(一)——二叉堆

十年热恋 提交于 2019-12-04 01:39:36
二叉堆的抽象数据类型: 1 #ifndef _BinHeap_H 2 #define ElementType int 3 #define MinElement -1000 4 struct HeapStruct; 5 typedef struct HeapStruct *PriorityQueue; //结构体指针 6 PriorityQueue Initialize(int MaxElements); //初始化一个二叉堆 7 void Destroy(PriorityQueue H); //销毁二叉堆的操作 8 void MakeEmpty(PriorityQueue H); //置空一个二叉堆的操作 9 void Insert(ElementType X, PriorityQueue H); //插入操作 10 ElementType DeleteMin(PriorityQueue H); //删除最小元的操作 11 ElementType FindMin(PriorityQueue H); //找到最小元的操作 12 int IsEmpty(PriorityQueue H); //判断二叉堆是否为空的操作 13 int IsFull(PriorityQueue H, int MaxElement); //判断二叉堆是否已满的操作 14 PriorityQueue

二叉堆的介绍和Java实现

蓝咒 提交于 2019-12-03 20:33:35
一、堆和二叉堆 堆,英文名称Heap,所谓二叉堆(也有直接称二叉堆为堆的), 本质上是一个完全二叉树,前面也提到过,如果树接近于完全二叉树或者满二叉树,采用顺序存储代价会小一点,因此常见的二叉堆均是顺序实现的。 按照排列的顺序可以分为最大堆和最小堆,最大堆的特征是父节点一定大于(依据情况判断是大于等于还是严格大于,数据结构归根到底还是用来使用的)子节点的数据。同样,有最大堆就会有最小堆,最小堆的 父节点数据小于其子节点的数据,因此根节点的数据是最小的。 二、二叉堆的插入和删除 来源: https://www.cnblogs.com/lbrs/p/11807252.html

【转】数据结构图文解析之:二叉堆详解及C++模板实现

匿名 (未验证) 提交于 2019-12-02 23:47:01
以下转载自 http://www.cnblogs.com/QG-whz/p/5173112.html 阅读目录 0. 数据结构图文解析系列 1. 二叉堆的定义 2. 二叉堆的存储 3. 二叉堆的具体实现 3.1 二叉堆的抽象数据类型 3.2 二叉堆的插入 3.3 二叉堆的删除 3.4 其余操作 4. 二叉堆代码测试 5. 大顶堆、小顶堆完整代码下载 正文 回到顶部 数据结构系列文章 数据结构图文解析之:树的简介及二叉排序树C++模板实现. 数据结构图文解析之:AVL树详解及C++模板实现 数据结构图文解析之:二叉堆详解及C++模板实现 回到顶部 二叉堆是一种特殊的堆,二叉堆是完全二叉树或近似完全二叉树。二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆。 当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆。 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。 回到顶部 二叉堆一般使用 数组 来表示。请回忆一下二叉树的性质,其中有一条性质: 性质五:如果对一棵有n个节点的完全二叉树的节点按层序编号(从第一层开始到最下一层,每一层从左到右编号,从1开始编号),对任一节点i有: 如果i=1 ,则节点为根节点,没有双亲。 如果2 * i > n ,则节点i没有左孩子 ;否则其左孩子节点为2*i .