优先队列Priority Queue和堆Heap

Posted will-zyq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优先队列Priority Queue和堆Heap相关的知识,希望对你有一定的参考价值。

对COMP20003中的Priority queue部分进行总结。图片来自于COMP20003


queue队列,顾名思义特点先进先出

priority queue优先队列,出来的顺序按照优先级priority大小,越大(小)的先pop。

普通的方法:

  Unsorted array:

    Construct: O(n)

    Get highest priority: O(n)

  Sorted array:

    Construct: O(n2)

    Get highest priority: O(1)

使用堆heap方法则可以:

    Construct:O(n)

    Get hishest priority: O(1)

  heap data structre: 完全树的数组(指针)形式(不一定是二叉树)。其每个节点满足优先级高于它的子节点。 本文主要讲binary heap形式的。

  技术分享图片

  从根节点开始编号放入数组中,为了后续操作方便,可以将数组[0]空出不用,从1开始(如上图,下面的文字叙述也按从1开始,将数组叫做A),因为完全树的关系,如果一个节点是A[i],则它的两个子节点则是A[2 * i]和A[2 * i + 1]。

  假定优先级越高越靠前,则第一个节点是(优先级)最大的,之后的都比它小,但左子树上的点和右子树上的点大小关系并不确定。

  当pop时,将第一个节点排出,将最后一个节点放到第一个节点的位置,然后从第一个节点位置开始进行downHeap操作修复堆(使得每个节点满足优先级高于它的子节点)。

  当push时,将新插入的节点接在末尾,从末尾开始进行upHeap操作修复堆(使得每个节点满足优先级高于它的子节点)。

  downHeap:从指定节点位置A[i]开始,与其两个子节点A[2 * i]和A[2 * i + 1]进行优先级比较(或与两个子节点中较大的那个进行比较),如果是A[i]最大,则停止,如果不是,则和较大的那个子节点交换位置,再继续与子节点进行比较,直到没有子节点时停止。

  upHeap:从指定位置A[i]开始,与其根节点A[i / 2]进行比较,如果根节点大,则停止,否则交换位置继续与根节点比较,直到没有根节点为止。

  两种建堆方法:

    1.插入一个节点,进行一次upHeap操作修复堆。   总复杂度O(nlogn)

    2.将全部节点插入后,从A[n / 2]到A[1]进行upHeap操作修复堆,即heapSort。看似复杂度还是O(nlogn),但实际上是O(n),因为只有一半的节点需要进行upHeap操作且只有A[1]的upHeap是O(logn),数学证明不懂,以后看看有没有时间补吧。。。

    技术分享图片

    技术分享图片

    技术分享图片

我的代码:

  https://raw.githubusercontent.com/Will-Zhu-27/Algorithms-and-Data-Structures/master/priorityQueue.c

  https://raw.githubusercontent.com/Will-Zhu-27/Algorithms-and-Data-Structures/master/priorityQueue.h



以上是关于优先队列Priority Queue和堆Heap的主要内容,如果未能解决你的问题,请参考以下文章

priority_queue优先级队列总结

优先级队列Priority_queue

数据结构 ---[实现 堆(heap)(包含方法图解过程) 优先队列(Priority Queue)]

优先队列 priority_queue

STL源码分析之heap和priority_queue

优先级队列-堆-STL实现