二叉堆(binary heap)

前言:

在前面学习了许多种排序之后,相信大家都已经学腻了排序,心里都会发牢骚说算法难道就只有排序吗,今天我们就不学习算法了,我们开始学习新的数据结构——二叉堆。

二叉堆:

二叉堆就是二叉树,完全的二叉树中每一个父节点下有两个子节点。今天我们以max_heap为例,就是传说中的最大堆,即每一个父节点都要比自己的两个子节点大,根节点最大,它大于整个二叉堆中的所有节点值。

我们用一个vector来表示二叉堆。原因呢,一是c++中的vector可以不断变化大小,来满足二叉堆的不断变化;二是用vector能够很好的表示二叉堆。舍去第一个元素,从1开始数,更加好理解,1。。。2,3。。。4,5,6,7.。。。。即k节点的子节点是2k与2k+1。

来看看二叉堆的一些操作:

swim操作:

当子节点大于父节点时,这自然是不符合二叉堆规则的,于是有swim操作来比较子节点与父节点的大小,若子节点大,则跟换子节点与父节点的值,不断更换直到根节点。

sink操作:

当父节点小于子节点时,这也是不符合二叉堆规则的,于是有sink操作来比较子节点与父节点的大小,若子节点大,则跟换子节点与父节点的值,不断更换到节点末端为止。

insert操作:

向二叉堆中插入元素就是先在二叉堆末端插入元素,然后利用swim操作来调整二叉堆,使插入的元素到合适的位置。

delmax操作:

delmax操作就是删去整个二叉堆中的最大值,即删去根节点。然而删去根节点之后我们若是往上填补的话操作很复杂,所以我们将根节点与二叉树最末端的节点交换,然后删去末节点,在使用sink操作来重新调整二叉堆中数字的位置。

来看看c++ 代码:

class binary_heap{
public:
    vector<int> pq;
    int N;

    binary_heap(int a[], int N = 0){
        int i;
        pq.push_back(-1);
        for(i = 0; i < N; i++){
            pq.push_back(a[i]);
        }
    }
    
    bool isEmpty(){
        return N == 0;
    }
    
    void insert(int x){
        N = N + 1;
        pq.push_back(x);
        swim(N);
    }
    
    int delMax(){
        int max;
        max = pq[1];
        exch(1, N);
        N = N - 1;
        pq.pop_back();
        sink(1);
        return max;
    }

    void swim(int k){
        while(k > 1 && less(k / 2, k)){
            exch(k, k / 2);
            k = k / 2;
        }
    }
    
    void sink(int k){
        while(2 * k <= N){
            int j = 2 * k;
            if(j < N && less(j, j + 1)){
                j = j + 1;
            }
            if(!less(k, j)){
                break;
            }
            exch(k, j);
            k = j;
        }
    }
    
    bool less(int i, int j){
        if(pq[i] < pq[j]){
            return true;
        }
        else{
            return false;
        }
    }
    
    void exch(int i, int j){
        int temp;
        temp = pq[i];
        pq[i] = pq[j];
        pq[j] = temp;
    }
};

总结:

随着堆的不断深入研究,发现了许多种堆,下面来看看这不同种堆的各种操作的复杂度:

(图片来自 Wikipedia,版权归其所有)

最后强烈推荐Coursera上普林斯顿大学的算法课点击打开链接

以上内容纯属个人学习总结,不代表任何团体或单位。若有理解不到之处请见谅!

猜你喜欢

转载自blog.csdn.net/qq_39747794/article/details/82055919