推荐博客 : 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;
}