堆排序
#include<stdio.h>
void swap(int* a, int* b) {
int c = *a;
*a = *b;
*b = c;
}
void adjust(int* nums, int start, int end) {
int father = start;//父亲节点下标
int child = 2 * father + 1;
//向下调整最大堆结构
while (child <= end) {//保证孩子存在才能调整
if (child + 1 <= end && nums[child] < nums[child + 1]) {
child++;
}
//保证child是左右孩子中最大的下标
if (nums[child] > nums[father]) {
swap(&nums[child], &nums[father]);
father = child;
child = 2 * father + 1;
}
else{//因为child可能刚好等于end 且 他的值不会比父亲节点的值大
break;//避免陷入死循环
}
}
}
void heapsort(int* nums, int n) {
//初始化堆,创建最大堆
//从最后一个父亲节点调整起 n/2-1
//一直调整到第一个父亲节点 0
for (int i = n / 2 - 1; i >= 0; i--) {
adjust(nums, i, n - 1);
}
//堆顶跟待排序序列最后一个元素进行交换
//j表示的是待排序序列最后一个元素下标
for (int j = n - 1; j >= 1; j--) {
swap(&nums[0], &nums[j]);
//重新调整堆结构形成最大堆
//由于j作为下标的位置已经交换成最大的,那么
//最后一个元素的下标应该再减一
adjust(nums, 0, j - 1);
}
}
int main() {
int nums[] = { 5,4,2,1,6,3,8 };
int n = sizeof(nums) / sizeof(int);
heapsort(nums, n);
for (int i = 0; i < n; i++) {
printf("%d", nums[i]);
}
return 0;
}