c++ 堆和堆排序的基本实现

文章目录

实现

#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>

using namespace std;

class HeapSorter {
private:
    vector<int> *data;
    function<bool(const int, const int)> func;
    int sz;
    enum class heap_status {
        UnReady = -1,
        Ready = 0,
        PoPing = 1,
        Sorted = 2,
    };
    heap_status status;

    bool comp(int l, int r) const {
        return func((*data)[l], (*data)[r]);
    }

    void sift_down(int start) {
        int parent = start;
        if (sz < 2 || (sz - 2) / 2 < parent)
            return;
        int child = 2 * parent + 1;
        if ((child + 1) < sz && comp(child, child + 1)) {
            ++child;
        }
        if (comp(child, parent)) {
            return;
        }
        int top = (*data)[parent];
        do {
            (*data)[parent] = (*data)[child];
            parent = child;
            if ((sz - 2) / 2 < child) {
                break;
            }
            child = 2 * child + 1;
            if ((child + 1) < sz && comp(child, child + 1)) {
                ++child;
            }
        } while (!func((*data)[child], top));
        (*data)[parent] = top;
    }

public:
    explicit HeapSorter(const function<bool(const int, const int)> &func = greater<>{}) : func(func) {
        data = nullptr;
        sz = -1;
        status = heap_status::UnReady;
    }

    void make_heap(vector<int> *data) {
        if (data == nullptr) {
            return;
        }
        if (data->empty()) {
            throw logic_error("empty array");
        }
        this->data = data;
        this->sz = data->size();
        status = heap_status::Ready;
        if (sz > 1) {
            for (int start = sz / 2; start >= 0; --start) {
                sift_down(start);
            }
        }
        if (sz <= 1) {
            status == heap_status::Sorted;
        }
    }

    void pop_heap() {
        if (status == heap_status::UnReady) {
            cout << "error data unready" << endl;
            return;
        }
        if (sz == 1) {
            --sz;
            return;
        }
        if (sz >= 1) {
            if (--sz == 0) {
                status = heap_status::Sorted;
                return;
            }
            status = heap_status::PoPing;
            swap((*data)[0], (*data)[sz - 1]);
            sift_down(0);
        }
        if (sz <= 1) {
            status == heap_status::Sorted;
        }
    }

    int pop_and_get() {
        if (status == heap_status::UnReady) {
            throw logic_error("error data unready");
        }
        int val = INT_MIN;
        if (sz >= 1) {
            val = data->front();
            pop_heap();
        }
        return val;
    }

    void sort() {
        if (status == heap_status::UnReady) {
            cout << "error data unready" << endl;
            return;
        }
        int left = sz;
        for (int i = 0; i < left; i++) {
            pop_heap();
        }
        status = heap_status::Sorted;
    }

    bool sorted() const {
        return status == heap_status::Sorted;
    }

    void print(string delim = "\t", string br = "\n") const {
        if (status == heap_status::UnReady) {
            cout << "error data unready" << endl;
            return;
        }
        if (status != heap_status::Sorted) {
            cout << "heap is not sorted" << endl;
        }
        for (auto v: *data) {
            cout << v << delim;
        }
        cout << br << flush;
    }
};

// 大顶堆排序后是升序, 因为最大值每次被换到了最后
HeapSorter bigHeap(less<>{});

// 小堆相反
HeapSorter minHeap{};

int main() {
    vector<int> ans = {2, 11, 9, 19, 10, 7, 8, 16, 12, 1, 3, 4, 7, 6, 5};
    bigHeap.make_heap(&ans);
    bigHeap.sort();
    bigHeap.print();

    minHeap.make_heap(&ans);
    minHeap.sort();
    minHeap.print();

    bigHeap.make_heap(&ans);
    bigHeap.sort();
    bigHeap.print();
}

输出

在这里插入图片描述

c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现
c++ 堆和堆排序的基本实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值