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



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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值