用堆二叉树实现,参考《算法》(第四版)。
1.优先队列
//二叉堆,从小到大排序
class heapBinaryTree
{
public:
heapBinaryTree(int capacity);//指定容量
heapBinaryTree(const int num[], int len);//用数组初始化堆
~heapBinaryTree();
inline int getCapacity(){return cap;}
inline int getLen(){return len;}
bool insert(int e);
int getMin();//取得最小值
int deleteMin();//删除并返回最小值
void showHeap();
private:
void sink(int pos);//将pos位置的元素下沉到合适的位置
void swim(int pos);
inline void swap(int num[], int pos1, int pos2);
private:
int len;//堆长度
int cap;//可扩展的最大容量
int *elem;//元素数组
};
实现:
heapBinaryTree::heapBinaryTree(int capacity)
{//申请空间,但不初始化数据
len=0;
cap=capacity;
elem=new int[capacity];
}
heapBinaryTree::heapBinaryTree(const int num[], int len)
{//使用已存在的数组数据进行初始化,并调整好堆
cap=len*2;
elem=new int[cap];
this->len=0;
for(int i=0;i<len;i++)
{
insert(num[i]);
}
}
heapBinaryTree::~heapBinaryTree()
{
delete[] elem;
}
inline void heapBinaryTree::swap(int num[], int pos1, int pos2)
{
int tmp=num[pos1];
num[pos1]=num[pos2];
num[pos2]=tmp;
}
void heapBinaryTree::sink(int pos)//下沉pos位置的元素到合适的位置
{
int childPos=pos*2;//计算子节点坐标
while(childPos<len)//如果左右有子节点
{
if(elem[childPos]>elem[childPos+1]) childPos++;//找到子节点中较小的
if(elem[pos]<=elem[childPos]) break;//如果比两个子节点都小,则不需要再下沉
swap(elem, pos, childPos);
pos=childPos;
childPos=pos*2;
}
if(childPos==len && elem[pos]>elem[childPos]) swap(elem, pos, childPos);//只有一个子节点的情