二叉堆
template<typename T,size_t _n>
struct hep{
int n;T *q;
hep(){n=0;q=new int[_n];}
~hep(){delete []q;}
void up(int i){ //上浮
for(;i>1;i>>=1)
if(q[i]<q[i>>1])swap(q[i],q[i>>1]);
}
void down(int i){ //下浮
while((i<<1)<=n){
int k=i<<1;
if(k<n&&q[k+1]<q[k])++k;
if(q[i]>q[k])swap(q[i],q[k]),i=k;
else return;
}
}
void push(const T& x){
q[++n]=x;up(n);
}
void pop(){
swap(q[1],q[n--]);
down(1);
}
T top(){return q[1];}
bool empty(){return n==0;}
};二项堆
定义:
- 度数为0的二项树只包含一个结点
- 度数为
的二项树有一个根结点,根结点下有
个子女,每个子女分别是度数分别为
的二项树的根
- 度数为
的二项树共有
个节点,深度为
处有
个节点。
- 每棵二项树都满足最小堆性质,即结点关键字大于等于其父结点的值
- 不能有两棵或以上的二项树有相同度数(包括度数为0)。换句话说,具有度数k的二项树有0个或1个。
比如的二进制为
,所以由度数为
的三棵树组成。
- 二项堆插入操作,平摊分析复杂度为
,
个节点的堆,最多有
棵树,查找,删除时间为
。
二项堆的内存结构图:
template<typename T>
struct BinomiaNode{
BinomiaNode():degree(0){
val=0;
parent=NULL;child=NULL;next=NULL;
}
T val;
BinomiaNode *parent;
BinomiaNode *child;
BinomiaNode *next;
size_t degree;
};
template<typename T,typename node=BinomiaNode<T>>
class BinomiaHeap{
public:
BinomiaNode(){root=NULL;}
bool empty()const{return root==NULL;}
T top(){
assert(empty());
node *p=root;T key=root->val;
while(p){
if(p->val<key)key=p->val;
p=p->next;
}
return key;
}
void pop(){
erase(top());
}
void union_heap(BinomiaHeap<T> rhs){
if(rhs&&rhs.root)root=union_heap(root,rhs.root);
}
void insert(const T& key){
if(find(key))return;
node* rt=new node();
rt->val=key;
root=union_heap(root,rt);
}
bool find(const T& key){return search(root,key)!=NULL;}
void erase(const T& key){
root=erase(root,key);
}
private:
node* erase(node* rt,const T& key){
if(rt==NULL)return rt;
node *p=search(rt,key);
if(p==NULL)return rt;
node* parent=p->parent;
while(parent){
p->val^=parent->val^=p->val;
p=parent;parent=parent->parent;
}
node *prev=NULL;
node *pos=rt;
while(pos!=p)prev=pos,pos=pos->next;
if(prev)prev->next=p->next;
else rt=p->next;
rt=union_heap(rt,reverse(p->child));
p=NULL;return rt;
}
node* search(node* rt,const T& key){
node *child,*parent=rt;
while(parent){
if(parent->val==key)return parent;
else {
child=search(parent->child,key);
if(child)return child;
parent=parent->next;
}
}
return NULL;
}
node* reverse(node* rt){
if(rt==NULL)return rt;
node *_next,*tail=NULL;
rt->parent=NULL;
while(rt->next){
_next=rt->next;
rt->next=tail;
tail=rt;rt=_next;
rt->parent=NULL;
}rt->next=tail;
return rt;
}
void link(node* &child,node* &rt){
child->parent=rt;
child->next=rt->child;
rt->child=child;rt->degree++;
}
node* merge(node* h1,node* h2){
if(!h1)return h2;
if(!h2)return h1;
node* rt=NULL,*_next=NULL,*h=NULL;
while(h1&&h2){
if(h1->degree<=h2->degree)
h=h1,h1=h1->next;
else h=h2,h2=h2->next;
if(_next==NULL){
_next=h;rt=h;
}else{
_next->next=h;
_next=h;
}
if(!h1&&h2)_next->next=h2;
if(h1&&!h2)_next->next=h1;
}
return rt;
}
node* reverse_list(node* rt){
if(rt==NULL)return rt;
node* p=NULL;
while(rt){
node* q=rt;
rt=rt->next;
q->next=p;
p=q;
}
return p;
}
node* union_heap(node* h1,node* h2){
node* rt=merge(h1,h2);
if(rt==NULL||rt->next==NULL)return rt;
rt=reverse_list(rt);
stack<node*>S;
for(node *p=rt;p;p=p->next){
while(!S.empty()&&S.top()->degree==p->degree){
node* q=S.top();
link(q,p);
S.pop();
}
S.push(p);
}
node* p=NULL;
while(!S.empty()){
node* q=S.top();
S.pop();
q->next=p;
p=q;
}
return reverse_list(p);
}
node *root;
};合并操作:
删除操作:

京公网安备 11010502036488号