#include <iostream> #include <cassert> using namespace std; // 最大索引堆:在普通堆的基础上,开辟一个存放索引的数组。 template <typename T> class IndexMaxHeap { private: T *data; // 存放最大索引堆的数据 int *index; // 存放最大索引堆的索引 int capacity; // 容量 int count; // 索引堆的元素个数 // 索引堆中, 数据之间的比较根据 data 的大小进行比较, 但实际操作的是索引 void shiftUp(int i) { while (i > 1 && data[index[i/2]] < data[index[i]]) { swap(index[i/2], index[i]); i /= 2; } } void shiftDown(int i) { while (2 * i <= count) { int j = 2 * i; if (j + 1 <= count && data[index[j]] < data[index[j+1]]) { j++; } if (data[index[i]] >= data[index[j]]) break; swap(data[index[i]], data[index[j]]); i = j; } } public: IndexMaxHeap(int capacity) { data = new T[capacity + 1]; index = new int[capacity + 1]; count = 0; this->capacity = capacity; } ~IndexMaxHeap() { delete[] data; delete[] index; } int size() { return count; } // 判断索引堆是否为空 bool isEmpty() { return count == 0; } // 插入元素,向最大索引堆插入一个新的元素,元素的索引为 i, 元素为 item // 对于用户来说,索引是从 0 开始 void insert(int i, T item) { assert(count + 1 <= capacity); assert(i + 1 >= 1 && i + 1 <= capacity); i = i + 1; data[i] = item; count++; index[count] = i; // 向存储索引的数组尾端插入索引 shiftUp(count); // 调整存储索引的堆 } // 从最大堆中取出最大元素,即为存放索引的堆的堆顶索引,所对应的元素 T extractMax() { assert(count > 0); T ret = data[index[1]]; // 最大元素 // 调整存储索引的堆 swap(index[1], index[count]); count--; shiftDown(1); // 调整存储索引的堆 return ret; } // 从最大堆中取出存放索引的堆的堆顶索引 int extractMaxIndex() { assert(count > 0); int ret = index[1] - 1; // 用户,从索引 0 开始 swap(index[1], index[count]); count--; shiftDown(1); return ret; } // 从索引堆中取出最大元素 T getMax() { assert(count > 0); return data[index[1]]; } // 从索引堆中取出最大元素对应的索引 int getMaxIndex() { assert(count > 0); return index[1] - 1; } // 获取最大索引堆中索引为i的元素 T getItem(int i) { assert(i + 1 >= 1 && i + 1 <= capacity); return data[i+1]; } // 将最大索引堆中索引为 i 的元素修改为 newItem void change(int i, T newItem) { i += 1; data[i] = newItem; // 找到indexes[j] = i, j表示data[i]在堆中的位置 // 之后shiftUp(j), 再shiftDown(j) for (int j = 1; j <= count; j++) { if (index[j] == i) { shiftUp(j); shiftDown(j); return; } } } }; template <typename T> void heapSort(T arr[], int n) { IndexMaxHeap<T> indexMaxHeap = IndexMaxHeap<T>(n); for (int i = 0; i < n; i++) { indexMaxHeap.insert(i, arr[i]); } indexMaxHeap.change(5, 88); for (int i = n - 1; i >= 0; i--) { arr[i] = indexMaxHeap.extractMax(); } } int main() { int arr[] = {100, 18, 9, 9, 53, 63, 42, 37, 3, 1}; int arrLength = sizeof(arr) / sizeof(arr[0]); heapSort(arr, arrLength); for (int i = 0; i < arrLength; i++) { cout << arr[i] << " "; } cout << endl; return 0; }