最小堆的插入与删除

最小堆的概念:堆顶元素是堆中最小元素,左右孩子均小于父节点的值,它就是最小堆。最大堆同理。最小堆是优先队列,一般存储在数组中。

C语言代码:

#include <iostream>
using namespace std;
class Heap{
private:
    int * heap;
    int size;
    int maxsize;
public:
    Heap(int sz):size(0),maxsize(sz){
        if(sz>0)
            heap = new int[sz];
    }
    ~Heap(){
        delete []heap;
    }
    //插入新元素
    bool push(int x){
        if(size==maxsize)
            return false;
        int i = size++;
        while(i>0){
            int p = (i+1)/2-1;
            if(x<heap){
                heap = heap;
                i = p;
            }else{
                break;
            }
        }
        heap = x;
        return true;
    }
    //将数组中的元素全部插入堆中
    bool pushArray(int a[],int n){
        for(int i=0;i<n;i++)
            push(a);
    }
    //输出整个数列
    void output(){
        for(int i=0;i<size;i++)
            cout<<heap<<" ";
            cout<<endl;
    }
    //删除元素
    bool shift(int &x){
    /*
     *删除一个元素,应该将最后一个元素放到堆顶,这时他的左右两个子树都是堆
     *比较左孩子右孩子,较小着上移直至最小着到堆顶形成堆
     * */
        if(0==size)
            return false;
        x = heap[0];
        heap[0] = heap[size-1];
        size--;
        //当左子树为空时退出循环
        int p = 0;
        int l = p*2+1;
        while(l<size){
            //右子为空就是左子 不空才比较左右孩子
            int r = p*2+2;
            int min = r<size ? (heap[l]<heap[r] ? l : r) : l;
            //交换两个数 这里并不能保证子女中的较小者一定比父节点的小
            if(heap[min]<heap){
                int tmp = heap;
                heap = heap[min];
                heap[min] = tmp;
            }
            p = min;
            l = p*2+1;
        }
        return true;
    }
};
int main(void){
    Heap h(10);
    int a[] = {3,5,8,2,1,7};
    h.pushArray(a,6);
    int x;
    for(int i=0;i<6;i++){
        h.shift(x);
        cout<<x<<" ";
        h.output();
    }
    return 0;
}

由完全二叉树知n个节点的树深度h=log2(n+1),那么插入与删除操作的渐进时间复杂度即为log2n,而建立堆要插入n个节点 因此建堆的时间复杂度为nlog2n