算法导论笔记-第六章-堆排序

6.1 堆
堆是一个数组,也可以被看作近似的完全二叉树。树上的每一个结点都对应数组中的一个元素。除了最底层,该树是完全充满的。
可以用某一数组代表堆,其中包含两个属性:
A.length 代表给出的数组元素的数目
A.heap-size 代表又多少个堆元素存储在该数组中

(树性质:
前提:近似完全二叉树,从左到右排序,i为某结点编号
其父结点为:i/2
左孩子:2i
右孩子:2i+1

高度:该结点到叶结点最长简单路径上边的数目
(n个元的的堆,高度为[lg2](向下取整))

叶结点下标:n表示数组存储的n个元素时,叶节点下标分别为[n/2]+1,[n/2]+2,[n/2]+3.....

最大堆:某个结点的值最大与其父结点相同。 //A[PARENT(i)] >=A[i]
最小堆:某个结点的值最小与其父结点相同。 //A[PARENT(i)] <=A[i]

6.2 维护堆的性质
MAX-HEAPIFY过程:时间复杂度为O(lg n) 维护堆的关键。
伪代码
MAX-HEAPIFY(A,i)
l=LEFT(i)
r=RIGHT(i)
if l<=A.heap-size and A[l]>A[i]
largest = l
else
if r<=A.heap-size and A[r]>A[i]
largest = r
if largest != i
exchange A[i] with A[largest]
MAX-HEAPIFY(A,largest)
C实现:
int RIGHT(int i) {
return 2 * i + 1;
}
int LEFT(int i){
return 2* i;
}


void MAX_HEAPIFY(int A[], int i)
{
int A_heap_size = 10;
int l = LEFT(i);
int r = RIGHT(i);
int largest = i;
if (l<=A_heap_size && A[l]>A[i]) {
largest = l;
}
if (r<=A_heap_size && A[r]>A[largest] ){
largest = r;
}
if (largest != i) {
int temp=A[i];
A[i] = A[largest];
A[largest] = temp;
MAX_HEAPIFY(A,largest);
}
}
BUILD-MAX-HEAP过程:线性时间复杂度,功能时从无序的输入数据数组中构造一个最大堆。
伪代码:
BUILD-MAX-HEAP(A)
A.heap-size = A.length
for i = [A.length/2] downto 1
MAX-HEAPIFY(A,i)dd
C实现:
void BUILD_MAX_HEAP(int A[],int length) {
int A_heap_size = length;
int i = length;
for (i; i > 0; i--) {
MAX_HEAPIFY(A, i, A_heap_size);
}
}
HEAPSORT过程:时间复杂度为O(lg n),功能时堆一个数组进行原址排序。
伪代码:
HEAPSORT(A)
BUILD-MAX-HEAP(A)
for i=A.length downto 2
exchangeA[1] with A[i]
A_heap-size--
MAX-HEAPIFY(A,1)
C语言实现:void HEAPSORT(int A[],int length) {
int A_heap_size = length;
int i = length;
BUILD_MAX_HEAP(A, A_heap_size);
for (; i > 1; i--){
int temp = A[1];
A[1] = A[i];
A[i] = temp;
A_heap_size--;
MAX_HEAPIFY(A, 1, A_heap_size);
}
}
MAX-HEAP-INSERT,HEAP-EXTRACT-MAX,HEAP-INCREASE-KEY,HEAP-MAXIMUM过程:
时间复杂度O(lg n),功能时利用堆实现一个优先队列。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章