算法描述直接看头文件吧
c++代码实现:
#ifndef _sort_heap__hh #define _sort_heap__hh /** 堆排序, O(nlgn), 原地排序 利用完整二叉树, 每次生成最大堆, 此时根节点就是最大值, 保存到队列最后, 然后继续剩下的 HEAP_SORT(A, size) BUILD_MAX_HEAP(A, size) heapsize = size; for i = size downto 1 exchange A[i], A[1]; // 最大值保存到最后 heapsize --; MAX_HEAPIFY(A, heapsize, 1); // 重新生成最大树, heapsize BUILD_MAX_HEAP(A, size) for i = size/2 downto 1 // size/2 之后的都是叶子, 没有必要对叶子执行 MAX_HEAPIFY MAX_HEAPIFY(A, size, i); MAX_HEAPIFY(A, size, i) l = i*2, r = i*2+1; // 完整二叉树的性质 largest = i; if l < size and A[l] > A[i] // 比较左儿子 largest = l; if r < size and A[r] > A[largest] // 比较右儿子 largest = r; if largest != i // 是否置换, 如果置换需要继续处理置换后的节点 exchange A[i], A[largest] MAX_HEAPIFY(A, size, largest); */ /** 保持第 i 个节点及其孩子满足最大树 */ template<class T> inline void __max_heapify(T *array, size_t start, size_t size, size_t i) { // 因为是基于0的 #define LEFT(x) ((x<<1)+1) #define RIGHT(x) (LEFT(x)+1) size_t l = LEFT(i); size_t r = RIGHT(i); size_t largest = i; if (l < size && array[start + l] > array[start + i]) largest = l; if (r < size && array[start + r] > array[start + largest]) largest = r; if (largest != i) { T key = array[start + i]; array[start + i] = array[start + largest]; array[start + largest] = key; __max_heapify<T>(array, start, size, largest); } } /** 构建最大树 */ template<class T> inline void __build_max_heap(T *array, size_t start, size_t size) { for (size_t i = size/2; (int)i >= 0; i--) { __max_heapify<T>(array, start, size, i); } } /** HEAP_SORT */ template<class T> inline void algo_sort_heap (T *array, size_t start, size_t size) { size_t heapsize = size; __build_max_heap<T>(array, start, size); for (size_t i = size-1; i >= 1; i--) { T key = array[start+i]; array[start+i] = array[start]; array[start] = key; heapsize--; __max_heapify(array, start, heapsize, 0); // } } #endif // heap.h