您的位置:首页 > 其它

算法学习导论学习笔记-第6章 堆排序

2010-07-24 15:36 429 查看

6.1 堆

堆是一种完全二叉树,因此可以用数组A来表示。树的根为A[1],给定了某个结点的下标i,其父结点PARENT(i)、左儿子LEFT(i)、右儿子RIGHT(i)的下标可以简单地计算出来:

PARENT(i)

return i/2

LEFT(i)

return 2i

RIGHT(i)

return 2i+1

二叉堆有两种:最大堆和最小堆。在这两种堆中,结点内的数值都要满足heap property。在最大堆中,max-heap property是指除了根结点以外的每个结点i,有

A[PARENT(i)] >= A[i]

在最小堆中,min-heap property是指除了根结点以外的每个结点i,有

A[PARENT(i)] <= A[i]

6.2 保持堆的性质

MAX-HEAPIFY是对最大堆进行操作的重要子程序。其输入为一个数组A和下标i。当MAX-HEAPIFY被调用时,我们假定以LEFT(i)和RIGHT(i)为根的两棵二叉树都是最大堆,但这时A[i]可能小于其子女,这样就违反了max-heap property。MAX_HEAPIFY让A[i]在最大堆中“下降”,使以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)


当MAX-HEAPIFY作用在一棵以结点i为根的,大小为n的子树上时,其时间复杂度为O(lgn)。

6.3 建堆

我们可以自底向上地用MAX-HEAPIFY来将一个数组A[1..n]变成一个最大堆。

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


BUILD-MAX-HEAP的时间复杂度是O(n)。

6.4 堆排序算法

HEAPSORT(A)
BUILD-MAX-HEAP(A)
for  i from length[A] downto 2
do exchange A[1],A[i]
heap-size[A] = heap-size[A] – 1
MAX-HEAPIFY(A,1)


HEAPSORT的时间复杂度为O(nlgn)。其中 BUIDL-MAX-HEAP的时间为O(n), n-1次HEAP-MAX-HEAPIFY调用中每一次的时间代价为O(lgn)。



6.5 优先级队列

HEAP-MAXIMUM(A)
return A[1]


时间为0(1)

HEAP-EXTRACT-MAX(A)
if  heap-size[A] < 1
then error “heap underflow”
max = A[1]
A[1] = A[heap-size[A]]
heap-size[A] = heap-size[A] – 1
MAX-HEAPIFY(A,1)
return max


时间复杂度为O(lgn)。

HEAP-INCREASE-KEY(A,i,key)
if  key < A[i]
then error “new key is smaller than current key”
A[i] = key
while i>1 and A[PARENT(i)] < A[i]
do exchange A[i],A[PARENT(i)]
i = A[PARENT(i)]


时间复杂度为O(lgn)

MAX-HEAP-INSERT(A,key)
heap-size[A] = heap-size[A] + 1
A[heap-size[A]] = –MAX
HEAP-INCREASE-KEY(A,heap-size[A],key)


时间复杂度为O(lgn)

堆排序C实现:

#include <stdio.h>
#define Left(i)	((i) << 1)
#define Right(i)	(((i) << 1) + 1)
#define Parent(i)	((i) >> 1)
void swap(int *x,int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
void max_heapity(int a[],int i,int heapsize)
{
int largest,left,right;
left = Left(i);
right = Right(i);
largest = i;
if(left <= heapsize && a[left] > a[i])
largest = left;
if(right <= heapsize && a[right] > a[largest])
largest = right;
if(largest != i)
{
swap(&a[i],&a[largest]);
max_heapity(a,largest,heapsize);
}
}
void build_max_heap(int a[],int heapsize)
{
int i;
for(i = heapsize / 2; i >= 1; i--)
max_heapity(a,i,heapsize);
}
void heap_sort(int a[],int heapsize)
{
int i;
build_max_heap(a,heapsize);
for(i = heapsize; i>=2; i--)
{
swap(&a[1],&a[i]);
heapsize--;
max_heapity(a,1,heapsize);
}
}
int main()
{
int a[] = {0,10,19,8,7,6,5,4,3,2,1,12,14,9};
int heapsize = 13;
int i;
printf("before sort:");
for(i = 1; i <= heapsize; i++)
printf(" %d",a[i]);
printf("/n");
heap_sort(a,heapsize);
printf("after  sort:");
for(i = 1; i <= heapsize; i++)
printf(" %d",a[i]);
printf("/n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: