堆實現優先隊列,以及數組堆化和堆排序

#include <iostream>
using namespace std;

class MaxHeap {
    int *data;
    int capacity, count;

    bool isRoot(int n) {
        return n == 1;
    }

    bool isLeaf(int n) {
        return n > count / 2;
    }

    int root(int n) {
        return n / 2;
    }

    int left(int n) {
        return n * 2;
    }

    int right(int n) {
        return n * 2 + 1;
    }

    int getMaxChild (int n) {
        if (n * 2 == count)
            return left(n);

        return data[left(n)] > data[right(n)] ? left(n) : right(n);
    }

    void exchange(int *a, int i, int j) {
        if (i == j)
            return;

        a[i] ^= a[j];
        a[j] ^= a[i];
        a[i] ^= a[j];
    }

    void swim(int n) {
        if (isRoot(n))
            return;

        if (data[n] > data[root(n)]) {
            exchange(data, n, root(n));
        }

        swim(root(n));
    }

    void sink(int n) {
        if (isLeaf(n))
            return;

        int maxChild = getMaxChild(n);
        if (data[n] >= data[maxChild])
            return;

        exchange(data, n, maxChild);
        sink(maxChild);
    }

public:
    explicit MaxHeap(int capacity) : capacity(capacity), count(0) {
        data = new int[capacity + 1];
    }
    MaxHeap(int *a, int size, int capacity) : data(a), capacity(capacity), count(size) {}
    ~MaxHeap() {
        delete[] data;
    }
    MaxHeap(const MaxHeap&) = delete;
    MaxHeap& operator=(const MaxHeap&) = delete;

    bool insert(int value) {
        if (isFull())
            return false;

        data[++count] = value;
        swim(count);

        return true;
    }

    bool popMax(int &value) {
        if (isEmpty())
            return false;

        value = data[1];
        data[1] = data[count--];
        sink(1);

        return true;
    }

    bool isEmpty() {
        return count == 0;
    }

    bool isFull() {
        return count == capacity;
    }

    int size() {
        return count;
    }

    void makeHeap() {
        for (int i = count / 2; i > 0; --i)
            sink(i);
    }

    void sortHeap() {
        for (int i = count; i > 0; --i) {
            exchange(data, 1, i);
            MaxHeap tmp(data, i - 1, capacity);
            tmp.sink(1);
        }
    }

    bool isMaxHeap() {
       for (int i = 1; !isLeaf(i); ++i) {
           if (data[i] < data[getMaxChild(i)])
               return false;
       }
       return true;
    }
};

bool test(MaxHeap &maxHeap) {
    int a[] = {4,7,3,1,8,2,5,0,9,6};
    int size = sizeof(a) / sizeof(*a);

    if (!maxHeap.isEmpty()) {
        cout << __LINE__ << " heap should empty" << endl;
        return false;
    }

    for (int i = 0; i < size; ++i) {
        if (!maxHeap.insert(a[i])) {
            cout << __LINE__ << " insert failed" << endl;
            return false;
        }
        if (maxHeap.size() != i + 1) {
            cout << __LINE__ << " size = " << maxHeap.size() << ", but expect " << i + 1 << endl;
            return false;
        }
    }

    if (!maxHeap.isMaxHeap()) {
        cout << __LINE__ << " should be heap" << endl;
        return false;
    }

    int value;
    for (int i = 0; i < size; ++i) {
        if (!maxHeap.popMax(value)) {
            cout << __LINE__ << "  pop failed" << endl;
            return false;
        }
        if (maxHeap.size() + i + 1 != size) {
            cout << __LINE__ << " size = " << maxHeap.size() << ", but expect "
                 << size - i - 1 << endl;
            return false;
        }
        if (value + i != size - 1) {
            cout << __LINE__ << " value = " << value << ", but expect "
                 << size - i - 1 << endl;
            return false;
        }
    }

    if (maxHeap.popMax(value)) {
        cout << __LINE__ << " heap should empty" << endl;
        return false;
    }

    return true;
}

bool testMakeHeap() {
    int a[] = {-1,4,7,3,1,8,2,5,0,9,6};
    int size = sizeof(a) / sizeof(*a) - 1;
    MaxHeap maxHeap(a, size, size);

    maxHeap.makeHeap();

    if (!maxHeap.isMaxHeap()) {
        cout << __LINE__ << " should be heap" << endl;
        return false;
    }

    maxHeap.sortHeap();

    for (int i = 1; i <= size; ++i) {
        cout << a[i] << ", ";
    }
    cout << endl;

    for (int i = 1; i <= size - 1; ++i) {
        if (a[i] > a[i + 1])
            return false;
    }

    return true;
}

int main() {
    MaxHeap maxHeap(100);
    cout << boolalpha << test(maxHeap) << endl;
    cout << boolalpha << testMakeHeap() << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章