堆和优先队列

#include <iostream>
using namespace std;

class Heap {
private:
    int *data;
    int capacity;
    int size;
    void update(int pos,int n) {
        int father = pos;
        int lchiled = father*2+1,rchiled = 2*father+2;
        while(lchiled<n || rchiled<n) {
            int max_index = father;
            if(lchiled<n && data[lchiled] > data[max_index]) max_index = lchiled;
            if(rchiled<n && data[rchiled] > data[max_index]) max_index = rchiled;
            if(max_index != father)
                swap(data[max_index],data[father]);
            else 
                break;
            father = max_index;
            lchiled = father*2+1,rchiled = 2*father+2;
        }
    }
public:
    Heap(int intput_capacity) {
        data = new int[intput_capacity];
        capacity = intput_capacity;
        size = 0;
    }
    ~Heap() {
        delete[] data;
    }
    void push(int value) {
        data[size] = value;
        int son = size;
        int father = (son-1)/2;
        while(data[son] > data[father]) {
            swap(data[father],data[son]);
            son = father;
            father = (son-1)/2;
        }
        size ++;
    }
    void heap_sort() {
        for(int i=size-1;i>=0;i--) {
            swap(data[0],data[i]);
            update(0,i);
        }
    }
    void output() {
        for(int i=0;i<size;i++) {
            cout<<data[i]<<" ";
        }
        cout<<"\n";
    }
    int top() {
        return data[0];
    }
    void pop() {
        swap(data[size-1],data[0]);
        update(0,size-1);
        size --;
    }
};

线性建堆

上面方法通过push的方式建堆的的时间复杂度为O(NlogN)级别,我们不妨利用上面的堆排序方法进行排序,主函数测试如下:

int main() {
    Heap heap(10);
    int arr[10] = {9,8,7,6,5,4,3,2,1,0};
    for(int i=0;i<10;i++) {
        heap.push(arr[i]);
    }
    heap.heap_sort();
    heap.output();
    return 0;
}

我们可以利用线性建堆的方法,使建堆的效率优化到O(N)

#include <iostream>
using namespace std;


void update(int *data,int pos,int n) {//自上向下调整,pos为开始调整的点位置,n为调整末结点的后一位
    int father = pos;
    int lchiled = father*2+1,rchiled = 2*father+2;
    while(lchiled<n || rchiled<n) {
        int max_index = father;
        if(lchiled<n && data[lchiled] > data[max_index]) max_index = lchiled;
        if(rchiled<n && data[rchiled] > data[max_index]) max_index = rchiled;
        if(max_index != father)
            swap(data[max_index],data[father]);
        else 
            break;
        father = max_index;
        lchiled = father*2+1,rchiled = 2*father+2;
    }
}


void heap_sort(int *data,int size) {
    for(int i=size/2-1;i>=0;i--)//线性建堆
        update(data,i,size);
    for(int i=size-1;i>=0;i--) {
        swap(data[0],data[i]);
        update(data,0,i);
    }
}
void output(int *data,int size) {
    for(int i=0;i<size;i++) {
        cout<<data[i]<<" ";
    }
    cout<<"\n";
}

int main() {
    int arr[10] = {9,8,7,6,5,4,3,2,1,0};
    heap_sort(arr,10);
    output(arr,10);
    return 0;
}