堆(Heap)的实现

来源:互联网 发布:知合控股 华夏幸福 编辑:程序博客网 时间:2024/05/18 00:10

学习了 Heap,其实不难。

用途:在 O(log(n)) 的时间内插入、返回和删除最大值或最小值。


它是这样一颗二叉树,父节点的值总是大于(小于)子节点的值(为了方便,我们把这句称作“要求”)。

显然,Heap 的树根就是那个动态的最大值或最小值。


首先需要一个维护堆的性质的函数 heapify,它的作用是,当以节点 i 为根的堆不满足要求时,调用这个函数使其满足要求。

其实思路也好想,对于某个节点 i ,如果它的值小于子节点的值,那么就将它与两个子节点的值的较大者交换位置。


然后是建立,思路是从底向上建立。而且为了方便,我们把树建立成一棵完全二叉树的形式。

最后一层显然不需要调整,对于倒数第二层,如果需要调整,我们就调用 heapify。

这样一直循环到第一层即可。


还有是插入,插入的时候,将新加入的值加到树的底部,然后不断向上更新,这样不会影响其他子树的堆的性质。


最后是删除,删除的时候,将树底的点换到树根,然后对树根调用 heapify 函数就行了。


/*    Title : Heap    Author: nyist_xiaod    Date  : 2013.3.14*/#include <stdio.h>#include <algorithm>using namespace std;#define L(x) (x<<1)#define R(x) (x<<1|1)const int N = 1e5+5;template<typename T>struct Heap{    int n;    T A[N];    Heap()    {        n = 0;    }    bool empty()    {        return n == 0;    }    void heapify(int u)    {        int max_i = u;        if(L(u) <= n && A[max_i] < A[L(u)])            max_i = L(u);        if(R(u) <= n && A[max_i] < A[R(u)])            max_i = R(u);        if(max_i == u)            return ;        swap(A[max_i],A[u]);        heapify(max_i);    }    void build()    {        for(int i=n/2;i>=1;i--)            heapify(i);    }    void insert(T x)    {        A[++n] = x;        int u = n;        while(u > 1 && A[u>>1] < x)        {            A[u] = A[u>>1];            u >>= 1;        }        A[u] = x;    }    void pop()    {        A[1] = A[n--];        heapify(1);    }    T top()    {        return A[1];    }};


原创粉丝点击