优先队列-堆

定义:堆是一种特殊的完全二叉树,(最小堆:所有父节点都比子节点小), 完全二叉树指除最右位置上有一个或多个叶节点缺少外,其他都是丰满的;可以使用数组存储;

        堆两个重要操作:shiftdown,shiftup;  【堆顶元素编号为1,父子节点编号关系:父节点i, 左孩子i*2, 右孩子i*2+1】

void shiftdown(int i){ //需要向下调整节点编号i 
    int t,flag=0; //flag用来标记是否需要继续
    //至少有左儿子 
    while(i*2<=n && flag==0){
        if(h[i]>h[i*2]){
            t=i*2; 
        }
        
        if(i*2+1<=n){
            if(h[t]>h[i*2+1]){
                t=i*2+1;
            }
        }
        
        if(i!=t){
            swap(i,t);
            i=t; //更新i,便于继续向下调整 
        }else{
            flag=1; //可以结束向下调整 
        }
    }
} 

void shiftup(int i){
    int flag=0;
    if(i==1) return; //堆顶,无需调整 
    
    while(i!=1 && flag==0){
        if(h[i]<h[i/2]){
            swap(i,i/2);
            i=i/2; //更新i为它父节点,便于继续向上调整 
        }else{
            flag=1;
        }
    }
} 

 

建堆:从最后一个非叶节点(编号n/2)开始到根节点(编号1),逐个根据需要将当前节点向下调整,直到以当前节点为根节点的子树符合堆的特性,时间复杂度 O(N);

void create(){
    //从最后一个非叶节点到第一个节点依次进行向下调整 
    for(int i=n/2;i>1;i--){
        shiftdown(i);
    }
} 

 

posted @ 2015-12-02 23:19  chenyizh  阅读(125)  评论(0)    收藏  举报