diff --git a/include/HeapSort.h b/include/HeapSort.h new file mode 100644 index 0000000..8659907 --- /dev/null +++ b/include/HeapSort.h @@ -0,0 +1,121 @@ +// 版权所有 (c) ling 保留所有权利。 +// 除非另行说明,否则仅允许在DataStruct中使用此文件中的代码。 +// +// 由 ling 创建于 24-6-30. +// + +#ifndef DATASTRUCT_HEAPSORT_H_19 +#define DATASTRUCT_HEAPSORT_H_19 + +#include + +namespace ling { + /** + * 堆排序 + */ + template + class HeapSort { + private: + std::vector *list; + + protected: + virtual bool isBig(const T &, const T &) const = 0; + + [[nodiscard]] inline bool isLeft(int i) const { + return left(i) < list->size(); + } + + [[nodiscard]] inline bool isRight(int i) const { + return right(i) < list->size(); + } + + [[nodiscard]] inline int parent(int i) { + return (i - 1) / 2; + } + + [[nodiscard]] inline int left(int i) const { + return i * 2 + 1; + } + + [[nodiscard]] inline int right(int i) const { + return i * 2 + 2; + } + + /// 上滤 + void top(int i) { + while (i > 0 && isBig((*list)[i], (*list)[parent(i)])) { + std::swap((*list)[i], (*list)[parent(i)]); + i = parent(i); + } + } + + /// 下滤 + void bottom(int i, int size) { + while (true) { + int largest = i; + int l = left(i); + int r = right(i); + if (l < size && isBig((*list)[l], (*list)[largest])) { + largest = l; + } + if (r < size && isBig((*list)[r], (*list)[largest])) { + largest = r; + } + + if (largest != i) { + std::swap((*list)[i], (*list)[largest]); + i = largest; + } else { + break; + } + } + } + + void bottom(int i) { + int size = list->size(); + bottom(i, size); + } + + public: + explicit HeapSort(std::vector &list) { + this->list = &list; + if (this->list->size() <= 1) + return; + } + + void init() { + for (int i = parent(list->size() - 1); i >= 0; i--) { + bottom(i); + } + } + + void insert(T val) { + list->push_back(std::move(val)); + top(list->size() - 1); + } + + void sort() { + int n = list->size(); + for (int i = n - 1; i > 0; i--) { + std::swap((*list)[0], (*list)[i]); + bottom(0, i); + } + } + + }; + + template + class HeapSortDefault : public HeapSort { + protected: + bool isBig(const T &t, const T &t1) const override { + return t > t1; + } + + public: + explicit HeapSortDefault(std::vector &list) : HeapSort(list) { + } + }; + +} // ling + +#endif //DATASTRUCT_HEAPSORT_H_19 diff --git a/main.cpp b/main.cpp index c54a33d..333509c 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,9 @@ #include #include - +#include +#include +#include +#include class RedBlackTree : public ling::RedBlackTree { protected: @@ -13,13 +16,40 @@ protected: } }; +#define DATA_SIZE 10000000 + +//开始一个统计点 +#define StartStating(name) auto name = std::chrono::high_resolution_clock::now() + +//结束统计 +#define EndStating(name, text) do {auto __ling_end_time = std::chrono::high_resolution_clock::now(); \ +auto duration = std::chrono::duration_cast(__ling_end_time - name); \ +std::cout << text << ": " << std::fixed << std::setprecision(6) <<((double)duration.count() / 1000000) << " 秒(" << duration.count() <<" 微秒)" << std::endl;\ +}while(false) + int main() { - RedBlackTree tree; + std::random_device rd; + std::mt19937 gen(rd()); - for (int i = 0; i < 400000; i++) - tree.insert(i); + std::vector list; + list.reserve(DATA_SIZE); + std::uniform_int_distribution<> dis(1, DATA_SIZE * 10); + for (int i = 0; i < DATA_SIZE; i++) { - std::cout << "Max : " << tree.maximum()->value << std::endl; + list.push_back(dis(gen)); + } + StartStating(start); + ling::HeapSortDefault sort(list); + sort.init(); + sort.sort(); + EndStating(start, "排序耗时"); + + for (int i = 1; i < list.size(); i++) { + if (list[i] < list[i - 1]) { + std::cout << "错误!" << std::endl; + return -1; + } + } return 0; } diff --git a/src/HeapSort.cpp b/src/HeapSort.cpp new file mode 100644 index 0000000..cd51d72 --- /dev/null +++ b/src/HeapSort.cpp @@ -0,0 +1,10 @@ +// 版权所有 (c) ling 保留所有权利。 +// 除非另行说明,否则仅允许在DataStruct中使用此文件中的代码。 +// +// 由 ling 创建于 24-6-30. +// + +#include "HeapSort.h" + +namespace ling { +} // ling \ No newline at end of file