您的位置:首页 > 其它

《算法导论》第6章 堆排序 (2)优先级队列

2012-02-17 22:25 357 查看


6.5 优先级队列


在实际中堆的一个很常见的应用:用来实现高效的优先级队列。
优先级队列分为最大优先级队列和最小优先级队列。

最大优先级队列的一个应用是在一台分时计算机上进行作业调度。
需要在堆中的每个元素里存储对应对象的柄(handle)。

#include <stdio.h>
#define PARENT(i) ((i) / 2)

int heap_maximum(int A[])

{

return A[1];

}

// HEAP-MAXIMUM与HEAPSORT中的for循环体一样。
// 将最后一个元素挪到根位置,堆大小减一,保持堆性质。

int heap_extract_max(int A[], int *heapsize)

{

int max = A[1];

A[1] = A[*heapsize];

*heapsize -= 1;

max_heapify(A, *heapsize, 1);

return max;

}

// HEAP-INCREASE-KEY与MAX-HEAPIFY的区别:
// HEAP-INCREASE-KEY是当前结点的值增大了,因此要向上将父结点与该结点交换。
// MAX-HEAPIFY是保持当前结点为根的树是对,因此将当前结点与两个子结点比较,
// 向下逐层恢复堆的性质。
void heap_increase_key(int A[], int i, int key)

{

A[i] = key;

while (i > 1 && A[PARENT(i)] < A[i]) {

exchange(A, i, PARENT(i));

i = PARENT(i);

}

}

// 相当于将尾部元素从无穷小增大到key。

void max_heap_insert(int A[], int *heapsize, int key)

{

*heapsize += 1;

heap_increase_key(A, *heapsize, key);

}

// 习题6.5-7 需要注意的是尾部元素挪到删除位置后,有两种情况:
// 若比父结点小,则max_heapify,向下保持堆性质;
// 若比父结点小,则heap_increase_key向上。
// heap_delete(A, heapsize, 1)相当于heap_extract_max。

int heap_delete(int A[], int *heapsize, int i)

{

int key = A[i];

int last = A[*heapsize];

*heapsize -= 1;

if (last <= A[PARENT(i)]) {

A[i] = last;

max_heapify(A, *heapsize, i);

}

else {

heap_increase_key(A, i, last);

}

return key;

}

情况一:heap_delete(A, heapsize, 1)删除14,则9被挪到14的位置,
调用max_heapify(A, heapsize, 1)向下保持堆性质。

14
/ \
8 10
/ \ / \
4 7 9

情况二:heap_delete(A, heapsize, 4)删除4,则9被挪到4的位置,
调用heap_increase_key(A, 4, 9)。

14
/ \
8 10
/ \ / \
4 7 9

// 测试数据

int main(void)

{

int A[20] = { 0, 16, 4, 10, 14, 7, 9, 3, 2, 8, 1 };

int heapsize = 10;

build_max_heap(A, heapsize);

print(A, heapsize);

heap_extract_max(A, &heapsize);

print(A, heapsize);

heap_delete(A, &heapsize, 1);

print(A, heapsize);

return 1;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: