-
如下图所示,(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树。
○ 树上的每一个结点对应数组中的一个元素。
○ 除了最底层外,该树是完全充满的,而且是从左向右填充。
○ 上图以二叉树和数组形式展现的一个最大堆。每个结点圆圈内部的数字是它所存储的数据。结点上方的数字是它在数组中相应的下标。数组上方和下方的连线显示的是父-子关系:父结点总是在它的孩子结点的左边。该树的高度为3,下标为4(值为8)的结点的高度为1
○ 表示堆的数组A包括两个属性:A.length(通常)给出数组元素的个数,A.heap-size表示有多少个堆元素存储在该数组中。
○ 设A[1…A.heap-size…A.length],(根为A[1]),我们很容易得到给定结点i,它的父、左右子结点:PARTENT(i) return i/2; LEFT(i) reutrn 2*i; RIGHT(i) return 2*i+1;
-
二叉堆的两种形式以及性质
○ 最大堆§ 除了根以外的所有结点i,都要满足:
A[PARTENT(i)] >= A[i]○ 最小堆
§ 除了根以外的所有结点i都有:
A[PARTENT(i)] <= A[i] -
堆排序中使用的是最大堆,最小堆通常用于构造优先队列。
○ 若某一属性既适合最大堆也适合最小堆,则使用“堆”这一名词 -
基本过程
○ MAX-HEAPIFY(A, i):维护最大堆性质的关键,时间复杂度O(lgn)§ 假定根结点为LEFT(i)和RIGHT(i)的二叉树都是最大堆
§ 使以i为根结点的子树重新遵循最大堆的性质
§ 通过让A[i]的值在最大堆中“逐级下降”实现MAX-HEAPIFY(A, i) l = LEFT(i) r = RIGHT(i) if l <= A.heap-size and A[l] > A[i] largest = l else largest = i if r <= A.heap-size and A[r] > A[largest] largest = r if largest
○ BUILD-MAX-HEAP:从无序的输入数据数组中构造一个最大堆
§ 子数组A(n/2+1…n)中的元素都是树的叶结点(以它们作为根的子树也就是最大堆)
§ 对树中的其他结点都调用一次MAX-HEAPIFY来构建一个最大堆BUILD-MAX-HEAP(A) A.heap-size = A.length for i = A.length/2 downto 1 MAX-HEAPIFY(A, i)
○ HEAPSORT:对一个数组进行原址排序
§ BUILD-MAX-HEAP将输入的数组A[1…n]建成最大堆
§ 最大的元素总在根A[1],把它与A[n]交换,并去掉结点n(A.heap-size减1即可)
§ 此时新的根A[1]可能不是最大堆,因此调用MAX-HEAPIFY(A,1)来维护最大堆性质
§ 不断重复上述操作(直到堆只剩下一个元素),最终数组上的值按从小到大排序好。HEAPSORT(A) BUILD-MAX-HEAP(A) for i = A.length downto 2 exchange A[1] with A[i] A.heap-size = A.heap-size-1 MAX-HEAPIFY(A,1)
○ MAX-HEAP-INSERT
○ HEAP-EXTRACT-MAX
○ HEAP-INCREASE-KEY
○ HEAP-MAXIMUM
堆与堆排序
最新推荐文章于 2022-05-07 23:20:37 发布