《数据结构与算法分析c++描述》读书笔记五——优先队列(堆)

  引子:

       优先队列:顾名思义与普通的队列不同,其不同之处在于“优先”。出队的操作就不像普通的队列那样:先进先出,而是按某种性质选择一个最优项输出。例如:最大堆每次出队的元素是队列中最大的元素。

       优先队列的实现方式有链表和数组两种。使用链表方式:1)不需要队列按序排列,则插入操作总是O(1)时间;deleteMin(出队)操作每次都需要遍历整个链表找出最小元素需要O(N)时间;2)若保持队列按序排列,则插入操作总是遍历整个链表找到合适的位置插入,需要O(N)时间;deleteMin(出队)就只需要常熟时间O(1)。使用数组方式:这里用了查找二叉树的形式,它实现优先队列的插入、删除操作的时间都是O(logN),相比用链表方式更优。但是,二叉查找树还支持了许多优先队列用不着的性质,所以由此引出:二叉堆。

      二叉堆:作为堆,满足堆的两个性质:结构性质和堆序性质。

      二叉堆的结构性质:堆是一棵完全被填满的二叉树(完全二叉树),只有底层可能没有被填满,但是底层的元素都是从左到右填入的。

      二叉堆的堆序性质:堆(max堆)的每一个节点比他的所有子节点都大,这样根处存放的是堆的最大元素。

      因为堆的结构性质,使得堆用数组而不需要用链表的形式实现。如下图:

《数据结构与算法分析c++描述》读书笔记五——优先队列(堆)_第1张图片

节点i的左子树存放在2*i的位置,右子树存放在2*i+1的位置;且任意位置的元素j,其父节点的位置在j/2(向下取整数)的位置上。


       介绍完了二叉堆的性质,下面就要所二叉堆的操作。

        二叉堆最基本的操作就是插入和删除。插入操作就是在数组的末尾添加插入新的元素x,然后通过上滤的方式,把 x放在堆中合适的位置。删除操作就是删除根,然后把堆中最后一个元素y填入根中,通过下滤的方式,把y放在合适的位置。 

       在最开始把一个数组a变为二叉堆时一定会涉及建堆操作:从有子树的最大的一个位置 n=a.size()/2 开始向前做下滤操作,直到对根做完下滤操作为止。

       二叉堆的实现部分程序如下:

《数据结构与算法分析c++描述》读书笔记五——优先队列(堆)_第2张图片


《数据结构与算法分析c++描述》读书笔记五——优先队列(堆)_第3张图片

《数据结构与算法分析c++描述》读书笔记五——优先队列(堆)_第4张图片

《数据结构与算法分析c++描述》读书笔记五——优先队列(堆)_第5张图片

你可能感兴趣的:(数据结构与算法分析)