实现
#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++ 堆和堆排序的基本实现