优先级队列(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 * 2;
while(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;
}
}
//// 才疏学浅,如有不足,多多指正
本文介绍大根堆(data structure)的概念及其在优先级队列中的应用,包括大根堆的插入与删除操作的具体实现。同时给出了C++代码示例。

被折叠的 条评论
为什么被折叠?



