算法学习(二)——堆排序

堆排序是另一种排序算法,它是一种原地排序算法,其运行时间为O(nlgn),并且在任何时候,数组中只有常数个元素存储在数组以外。

在此之前要明确什么是堆,堆数组结构是一种数据对象,其可被视为是完全二叉树。树中每个结点与数组中的该结点值的那个元素对应。

表示堆的数组A有两个属性的对象:

length[A]是数组中的元素的个数

heap-size[A]是存放在A中的堆元素个数,也就是A[1..heap-size[A]]的元素是放在相应堆中,当然heap-size[A]]≤length[A]。

对于给定的某个结点i,

父结点下标: PARENT(i) return [i/2],(将i的二进制表示右移一位)

左儿子下标为 LEFT(i) return 2i ,(将i的二进制表示左移一位)

和右儿子的下标为 RIGHT(i) 2i+1。(将i的二进制表示左移移一位再在低位加一)

堆分最大堆和最小堆,暂且只讨论最大堆,除根结点以外的每个结点i,有A[PARENT[i]]≥A[i],即某个结点的值最多和其父结点的值一样大,所以根结点存放的即为堆的最大元素。

堆排序中有一些过程

对MAX-HEAPIFY(A, i)的调用,使得以i为根的子树成为最大堆,经过递归调用MAX-HEAPIFY(A, i)

MAX-HEAPIFY(A, i)
 
l  ← LEFT(i)
r  ← RIGHT(i)
if l ≤ heap-size[A] and A[l] > A[i]
    then largest ← l
    else largest ← i
if r ≤ heap-size[A] and A[r] > A[largest]
    then largest ← r
if largest ≠ i
    then exchange A[i] ↔ A[largest]
        MAX-HEAPIFY(A, largest)

 

建堆可以使用以下过程

BUILD-MAX-HEAP[A]
 
heap-size[A] = length[A] 
for i ← [length[A]/2] downto 1
    do MAX-HEAPIFY(A, i)

不难看出大于[length[A]/2]的结点都是堆的叶子结点,因此不需要构建最大堆,对剩余的结点,以其为子树的根结点构建最大堆,依次循环至根结点,则整个数组对应的堆也是最大堆。

 

下面对数组A[1…n]进行排序

HEAPSORT[A]

BUILD-MAX-HEAP[A]
for i ← length[A] downto 2 
    do exchange A[1] ↔ A[i]
        heap-size[A] ← heap-size[A] - 1
        MAX-HEAPIFY(A, 1)

首先构建最大堆,则根结点的元素为堆中的最大元素,从i为A的最末元素开始,将其与当前根元素替换,并且将i元素移出堆,再对剩下的堆元素进行MAX-HEAPIFY过程,构建最大堆。依次移除堆中的最大元素,按倒序仍然保存在数组A中,最终则对数组A完成了排序。

posted @ 2013-01-19 16:47  北纬以北  阅读(180)  评论(0编辑  收藏  举报