堆排序分为大根堆和小根堆。
堆排思想:(采用树的概念来组织数据结构,在这里我是根据小根堆对数据进行排序)
①首先我们Insertheap一组数据,在插入的过程中采用向上调整(Shiftup),每次将插入的最小值放在堆顶(heap[0]).
②然后我们Removeheap创建好的堆,将heap[0]节点剔除作为返回值,每次都将最后一个叶子节点赋值到heap[0],然后在执行向下调整(ShiftDown),查找到根节点以下最小的节点,重新创建小跟堆。
#include<iostream> #include<assert.h> using namespace std; #define DEFAULT_SIZE 10 //堆排 class BigHeap { public: BigHeap(int sz = DEFAULT_SIZE) { capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE; heap = new int[capacity]; cursize = 0; } ~BigHeap() { delete[]heap; heap = NULL; capacity = cursize = 0; } public: void Insert(int& x) { if (cursize >= capacity) return; heap[cursize] = x; ShiftUp(cursize); cursize++; } int RemoveHeap() { assert(cursize != 0); int key = heap[0]; heap[0] = heap[cursize - 1]; cursize--; ShiftDown(0); return key; } public: void ShiftUp(int pos) { int i = (pos - 1) / 2; int j = pos; int tmp = heap[j]; while (j > 0) { if (tmp < heap[i]) { heap[j] = heap[i]; j = i; i = (j - 1) / 2; } else break; } heap[j] = tmp; } void ShiftDown(int pos) { int i = pos; int j = i * 2 + 1; //父的左子树节点 int tmp = heap[i]; while (j < cursize) { if (j + 1 < cursize && heap[j] > heap[j + 1]) j++; if (heap[j] < tmp) { heap[i] = heap[j]; i = j; j = i * 2 + 1; } else break; } heap[i] = tmp; } private: int* heap; int cursize; int capacity; }; void HeapSort(int* a, int n) { BigHeap small(n); for (int i = 0; i < n; i++) small.Insert(a[i]); for (int i = 0; i < n; i++) { a[i] = small.RemoveHeap(); } } int main() { int arr[] = { 23,12,11,2,5,16,26,37,59,29 }; int n = sizeof(arr) / sizeof(int); HeapSort(arr, n); for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }