推荐博客 : https://blog.csdn.net/leex_brave/article/details/51490647
https://blog.csdn.net/rhx_qiuzhi/article/details/52422219
堆分为最大堆和最小堆,其一定是一颗完全二叉树,并且保证若其为最大堆时,根结点的值一定大于左右孩子结点的值。由于其是一颗完全二叉树,那么我们就可以用数组去实现一个堆。
如何构建一个堆:
1 . 每次插入一个新元素时,我们去维护这个堆
int n, m; int len = 1; int a[1005]; int parent(int x){ return x >> 1;} int lchild(int x){ return x<<1;} int rchild(int x){ return x<<1|1;} void heapify(int k){ int l = lchild(k); int r = rchild(k); int nmax; if (l <= len && a[l] < a[k]) nmax = l; else nmax = k; if (r <= len && a[r] < a[nmax]) nmax = r; if (nmax != k) swap(a[nmax], a[k]); } void build(int x){ a[len] = x; for(int i = parent(len); i >= 1; i = parent(i)){ heapify(i); } len++; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int x, st; cin >> n >> m; for(int i = 1; i <= n; i++){ cin >> x; build(x); } //for(int i = 1; i < len; i++) printf("%d ", a[i]); return 0; }
2 . 延伸出来了堆排序, 将所有元素按顺序存在数组中后在进行调换
int a[10] = {0, 1, 5, 2, 7, 4, 10, 6, 11, 15}; int len = 9; int parent(int x) {return x>>1;} int lchild(int x) {return x<<1;} int rchild(int x) {return x<<1|1;} void heapify(int x){ int nmax = x; int l = lchild(x); int r = rchild(x); if (l <= len && a[l] > a[x]){ nmax = l; } else nmax = x; if (r <= len && a[r] > a[nmax]){ nmax = r; } if (x != nmax){ swap(a[x], a[nmax]); heapify(nmax); } } void heapsort(){ for(int i = parent(len); i >= 1; i--){ heapify(i); //for(int i = 1; i <= 9; i++) printf("%d ", a[i]); //printf(" "); } for(int i = len; i > 1; i--){ swap(a[i], a[1]); len--; heapify(1); //for(int i = 1; i <= 9; i++) printf("%d ", a[i]); //printf(" ______________ "); } } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); heapsort(); for(int i = 1; i <= 9; i++) printf("%d ", a[i]); return 0; }