优先队列

《算法导论》第3版6.5讲解了优先队列

优先队列(priority queue)是一种用来维护由一组元素构成的集合S的数据结构,其中的每一个元素都有一个相关的值,称为关键字(key)。
一个最大优先队列支持以下操作:

1) insert(S, x): 把元素x插入集合S中,这一操作等价于S=S∪{x}

2) maximum(S): 返回S中具有最大键字的元素

3) extract_max(S): 去掉并返回S中具有最大键字的元素

4) increase_key(S, x, k): 将元素x的关键字增加到k,这里假设k的值不小于x的原关键字值

1)max_heap_insert:
void max_heap_insert(int A[], int key)
{
    ++heap_size;
    A[heap_size - 1] = INT_MIN;
    heap_increase_key(A, heap_size - 1, key);
}
2)heap_maximum:
int heap_maximum(int A[])
{
    return A[0];
}
3)heap_extract_max:
int heap_extract_max(int A[])
{
    if (heap_size < 1)
    {
        cout << "heap underflow" << endl;
        return -1;
    }

    int max = A[0];
    A[0] = A[heap_size - 1];
    --heap_size;
    max_heapify(A, 0);

    return max;
}
4)heap_increase_key:
void heap_increase_key(int A[], int i, int key)
{
    if (key < A[i])
    {
        cout << "new key is smaller than current key" << endl;
        return;
    }

    A[i] = key;
    while (i > 0 && A[parent(i)] < A[i])
    {
        swap(A[i], A[parent(i)]);
        i = parent(i);
    }
}

在《算法导论》第3版习题6.5-6提到:
在heap_increase_key的第5行的交换操作中,一般需要通过三次赋值来完成。想一想如何利用insertion_sort内循环部分的思想,只用一次赋值就完成这一交换操作?

思路:先向下移动小于key的祖先,直到没有小于key的祖先后放在空出的位置上

void heap_increase_key_oneassign(int A[], int i, int key)
{
    if (key < A[i])
    {
        cout << "new key is smaller than current key" << endl;
        return;
    }

    while (i > 0 && A[parent(i)] < key)
    {
        A[i] = A[parent(i)];
        i = parent(i);
    }

    A[i] = key;
}

在《算法导论》第3版习题6.5-8提到:
heap_delete(A, i)操作能够将结点i从堆A中删除。对于一个包含n个元素的堆,请设计一个能够在O(logn)时间内完成的heap_delete操作。

void heap_delete(int A[], int i)
{
    swap(A[i], A[heap_size - 1]);
    --heap_size;
    max_heapify(A, i);
}

void heap_delete_thevalue(int A[], int target)
{
    int tag = -1;
    for (int i = 0; i < heap_size; ++i)
    {
        if (A[i] == target)
        {
            tag = i;
            break;
        }
    }

    if (tag != -1)
        heap_delete(A, tag);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值