comet wannafly summer camp 数据结构篇之堆

二叉堆

一、堆的性质:根节点的权值大于等于子树中任意节点的权值;除最底层之外每一层都被添满—完全二叉树。

 

二、堆的操作:

1.获取最大值;直接把堆顶拿出来就是堆的最大值。

//heap[1];

 

 

2.新插入一个节点;将新增的节点放在n+1位,然后不断和父亲进行对比,如果不满足堆的性质就进行替换,否则就是一个符合标准的堆。【O(log n)】

 

void swap(int &x,int &y){int t=x;x=y;y=t;}
int heap[M];//定义堆数组
int siz;//堆大小 
void push(int x){//插入x
    heap[++siz]=x;
    now=siz;
    //插入到堆底 
    while(now!=1){//直到访问到堆顶 
        ll nxt=now>>1;//找到它的父亲 
        if(heap[nxt]>heap[now])swap(heap[nxt],heap[now]);//父亲比它大,那就交换 
        else break;//如果比它父亲小,那就代表着插入完成了 
        now=nxt;//交换 
    }
    return; 
}

 

 

 

3.删除最大值;找要删除的根的两个儿子中较大的那个,用根进行交换,不断将两个儿子中较大的那个换上一层,直到根节点1号点沉底,然后删除。可能最后一层会出现删除后不满足完全二叉树的性质,那个就将最后一个节点插入到沉底删除的位置。 

 

void pop(){
    swap(heap[siz],heap[1]);siz--;//交换堆顶和堆底,然后直接弹掉堆底 
    int now=1;
    while((now<<1)<=siz){//对该节点进行向下交换的操作 
        int nxt=now<<1;//找出当前节点的左儿子 
        if(nxt+1<=siz&&heap[nxt+1]<heap[nxt])nxt++;//看看是要左儿子还是右儿子跟它换 
        if(heap[nxt]<heap[now])swap(heap[now],heap[nxt]);//如果不符合堆性质就换 
        else break;//否则就完成了 
        now=nxt;//往下一层继续向下交换 
    }
}

 

 

 

4.新建一个堆(一个一个插入)

三、写法

(写法自由,任何可以实现树形结构的写法都可以,例如数组模拟、指针)

一般用数组模拟,即下标为x的节点的子树为2x和2x+1;

 

posted @ 2019-07-30 20:08  GeraldG  阅读(108)  评论(0)    收藏  举报