优先级队列之堆实现

本文介绍大根堆(data structure)的概念及其在优先级队列中的应用,包括大根堆的插入与删除操作的具体实现。同时给出了C++代码示例。
优先级队列(priority queue)是0个或多个元素的集合,每个元素都有一个优先权或值。优先级队列中,元素的出队列顺序不是同普通队列一样FIFO(先进先出),而是按照优先级递增或递减顺序,但不是元素进入队列的顺序。
堆(heap)[-数组表示]是实现优先级队列效率很高的数据结构。
堆即使完全二叉树又是大根树(或小根树),[ps:大根树指树中每个节点的值都大于或等于其子节点的值,小根树则相反]

以大根堆为例;
以下是大根堆的类代码:

class maxHeap
{
public:
    maxHeap(unsigned lenth = 50)
    {
        heapLenth = lenth;
        heap= new int[heapLenth];
        heapSize = 0;
    }
    void initialize(int *theheap, int theSize);
    void push(const int& theElement);
    void pop();
    int &top();
    unsigned size()
    {
        return heapSize;
    }

    bool empty()
    {
        return heapSize == 0;
    }

private:
    int *heap;
    unsigned heapSize;
    unsigned heapLenth;
};

功能实现:
这里写图片描述
大根堆的插入:
如图-上 所示,这里有一棵5元素的大根堆,我们现在将值为21的元素插入其中, 插入过程是这样的:
把新元素插入新节点,然后沿着新节点到根节点的路径,执行一趟起泡操作,将新元素与其父节点的元素比较交换,直到后者大于或等于前者为止。

void maxHeap::push(const int &theElement)
{
    int currentNode;
    currentNode = ++heapSize;
    while(currentNode != 1 && heap[currentNode / 2] < theElement)
    {
        heap[currentNode] = heap[currentNode / 2];
        currentNode /= 2;
    }
    heap[currentNode] = theElement;
}

大根堆的删除:
大根堆中删除一个元素,就是删除根节点的元素。
如图-下所示, 我们首先将根节点元素删除,我们的大根堆剩下了5个元素。此时的二叉树需要重新组织,以便乃是大根堆(即重构,以对应一棵完全二叉树)
为此,我们先将位置⑥的元素2取出,然后删除原来2所在的节点,这样就得到了一个完全二叉树,如第三步所示,因为此时的二叉树不是大根树,所以我们还需要做一步下沉的操作,我们将根节点不断向较大的子节点下沉,直到沉到最底部,或根节点的值大于子节点的值。
代码如下:

void maxHeap::pop()
{
    if(0 == heapSize){
        cout << "empty!";
        return ;
        }
    heap[1].~int();
    int lasttheElement = heap[heapSize--];
    int currentNode = 1;
    int child = 2;
    while(chile <= heapSize)
    {
        if(child < heapSize && heap[child] < heap[child + 1])
            child++;
        if(lasttheElement >= heap[child])
            break;

        heap[currentNode] = heap[child];
        currentNode =child;
        child *= 2;
    }
    heap[currentNode] = lasttheElement;
}

以下是大根堆初始化的代码:

void maxHeap::initialize(int *theheap, int theSize)
{
    delete []heap;
    heap = theheap;
    heapSize= theSize;

    for(int root = heapSize / 2; root >= 1; root--)
    {
        int rootElement = heap[root];
        int child = root * 2while(child <= heapSize)
        {
            if(child < heapSize && heap[child] < heap[child + 1])
                child++;
            if(rootElement >= heap[child])
                break;

            heap[child / 2] = heap[child];
            child *= 2;
        }
        heap[child / 2] = rootElement;
    }
}

//// 才疏学浅,如有不足,多多指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值