优先队列:使用了二叉堆来实现。
二叉堆:实际上是一颗被完全填满的二叉树。它具有堆序性。而最小值在根的位置。并且使用的是数组实现,一个I元素左儿子在2I上,右儿子在2I+1上。父亲则在I/2上。
为了保证堆序性,我们在插入和删除操作上要注意。在插入时我们就要调整整个堆保证每个子树的根节点最小。删除时也一样。
#include<new>
#include<iostream>
template <typename T>struct HeapNode{
int Capacity;
int Size;
T * Elements;
};
template <typename T> class PriorityQueue{
private:
typedef struct HeapNode<T> * Priorityqueue;
Priorityqueue H;
public:
Priorityqueue Initialize( int MaxElements )
{
H = new HeapNode<T>;
H->Elements = new T[MaxElements];
H->Capacity = MaxElements;
H->Size = 0;
H->Elements[0] = 0;//最小标志
return H;
}
void Insert( T X )
{
int i;
if( IsFull( ) )
{
return ;
}
for( i = ++H->Size ; H->Elements[i/2] > X ; i /= 2 )//从最后一个节点开始找到比插入值小的节点然后插入。
H->Elements[i] = H->Elements[i/2]; //父节点值给到子节点
H->Elements[i] = X;
}
T DeleteMin( )
{
int i, Child;
T MinElement ,LastElement;
if( IsEmpty() )
{
return H->Elements[0];
}
MinElement = H->Elements[1];//记录最小节点
LastElement = H->Elements[ H->Size-- ];//节点数减1并且保存在LastElement中
for( i = 1 ; i * 2 <= H->Size ; i = Child )//现在根节点为空依次上滤其他节点,并找到插入最后一个节点的位置I。
{
Child = i*2;
if( Child != H->Size && H->Elements[ Child + 1] < H->Elements[ Child ]);
Child++;
if( LastElement > H->Elements[Child] )
H->Elements[i] = H->Elements[Child];
else
break;
}
H->Elements[i] = LastElement;//把原本的最有一个元素放入I位置上。
return MinElement;
}
T FindMin( )
{
return H->Elements[1];
}
bool IsEmpty( )
{
if( H->Size == 0 )
return true;
else
return false;
}
bool IsFull( )
{
if( H->Size == H->Capacity )
return true;
else
return false;
}
PriorityQueue(T a[], int number)
{
H = Initialize( number * 2 );
for(int i = 0 ; i < number ; i++ )
{
Insert( a[i] );
}
}
~PriorityQueue()
{
delete []H->Elements;
delete H;
}
};
参考书籍:《数据结构与算法分析》