排序算法总结之堆排序 Heap Sort

来源:互联网 发布:java咖啡机公司 编辑:程序博客网 时间:2024/05/29 07:52

算法原理:


堆排序算法利用二叉堆进行排序。最大堆得到升序的数组,最小堆得到降序的数组。

1. 构建最大堆(最小堆)
2. 从堆中取出根节点
3. 维护最大堆(最小堆)


堆:

堆的是二叉树的一种,实际上是数组对象。树上的节点和数组中的元素相对应,每一层从左到右填满,只有最后一层可能不满。



数组下标从1开始时,父节点下标和左右节点下标的关系为:PARENT(i) = i/2      LEFT(i) = 2 * i        RIGHT(i) = 2 * i + 1

最大堆:A[PARENT(i)] >= A[i]                  最小堆: A[PARENT(i)] <= A[i]


堆的基本操作:

操作描述时间复杂度build建立一个空堆O(n)insert向堆中插入一个新元素O(\log n)update将新元素提升使其符合堆的性质 get获取当前堆顶元素的值O(1)delete删除堆顶元素O(\log n)heapify使删除堆顶元素的堆再次成为堆


算法伪代码:


算法伪代码出自算法导论堆排序部分:

1. 建堆,当堆的大小为n时,堆的叶子节点的下标为n/2+1, n/2+2,...n
BUILD-MAX-HEAP(A)
heap-size[A] = length[A]
for i=length(A)/2 to 1
do MAX-HEAPFY(A, i)

 2. 维护堆

MAX-HEAPFY(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-HEAPFY(A, largest)

3. 堆排序

HEAPSORT(A)

BUILD-MAX-HEAP(A)

for i=length[A] to 2

do exchange A[1] - A[i]

heap-size[A] = heap-size[A] - 1

MAX-HEAPFY(A, 1)


算法性能分析:


时间复杂度:分析堆排序算法的时间复杂度需要先分析建堆和维护堆的时间复杂度,而分析建堆的时间复杂度需要先分析维护堆的时间复杂度,因此从维护堆的时间复杂度开始分析。

维护堆(MAX-HEAPFY)时间复杂度:MAX-HEAPFY函数调整第i个元素使以i为根的堆成为最大堆,调整A[i], A[LEFT(i)]和A[RIGHT[I]]的代价为O(1), 然后递归的向下调整发生改变的子树使之保持最大堆。算法导论这部分书中为我们证明了每个子书大小最多为2n/3。因此,递归的时间复杂度计算公式可以写成:

T(n) <= T(2n/3) + O(1)

得到T(n) = O(logn)


建堆(BUILD-MAX-HEAP)的时间复杂度:从最后一个非叶子节点开始使用MAX-HEAPFY向上调整整棵树,每个子树都成为一个最大堆。每次MAX-HEAPFY的时间已经推出为O(logn), 调用的次数为O(n),因此所需的时间为O(nlogn)


堆排序算法时间复杂度:首先调用BUILD-MAX-HEAP把数组调整为最大堆,需要的时间复杂度为O(nlogn)。把堆顶元素和堆的最后一个元素交换,需要的时间为O(1), 然后调整剩下的元素维护最大堆,调用n-1次MAX-HEAPFY,需要的时间复杂度为O(nlogn)。因此,堆排序的时间复杂度为O(nlogn)。


空间复杂度:O(1)

稳定性:不稳定


Java版本实现代码:

private void build(int[] A){for(int i=A.length/2-1;i>=0;i--){heapfy(A, i, A.length);}}private void heapfy(int[] A, int i, int len){int left = 2*i+1;int right = 2*i+2;int largest;if(left < len && A[left]>A[i])largest = left;elselargest = i;if(right < len && A[right] > A[largest])largest = right;if(largest != i){int temp = A[i];A[i] = A[largest];A[largest] = temp;heapfy(A, largest, len);}}private void sort(int[] A){build(A);int size = A.length;while(size > 0){int temp = A[0];A[0] = A[size-1];A[size-1] = temp;size--;heapfy(A, 0, size);}}


1 0
原创粉丝点击