堆排序:
push:以数组保存,父节点下标为 i/2,左儿子下标 2*i,右儿子 2 *i+1,在末尾加入新元素,然后上移调整。在队列头前加入一个大数,以消除边界条件判断。
pop:末尾元素放到堆顶,然后下移。实际实现中,末尾的元素都只在最后才被放入空穴。
class Heap{//大顶堆
private:
vector<int> member;
int tail;
int top;
public:
Heap(){
tail=0;top=1;
member.push_back(0x3f3f3f3f);//为了消除边界条件的小trick
}
Top(){
if(tail>=top)
return member[top];
}
void push(int t){
int i;
member.push_back(t);
tail++;
for(i=tail; member[i/2] < t; i/=2)
member[i]=member[i/2];
member[i]=t;
}
int pop(){
int ret=member[1];
int i=1;
int x=member[tail--];
while(2*i<=tail){//有儿子,等于时只有左儿子
int l=2*i,r=2*i+1;
if(r<=tail && member[l]<member[r]) l=r;//若右儿子存在,选出要交换的儿子
if(member[l]<=x) break;//在合适的位置
member[i]=member[l];
i=l;
}
member[i]=x;
return ret;
}
isempty(){
return tail<top;
}
};