// 从位置i, 将父节点不断向下与子节点比较, 使得以i为跟的二叉树, 满足堆的性质
void heapify(vector<int>& nums, int n, int i) {
int largest = i; // 当前结点
int left = 2 * i + 1; // 左子结点
int right = 2 * i + 2; // 右子结点
if (left < n && nums[left] > nums[largest]) {
largest = left;
}
if (right < n && nums[right] > nums[largest]) {
largest = right;
}
if (largest != i) {
swap(nums[i], nums[largest]);
heapify(nums, n, largest); // 递归调整子树
}
}
void heapSort(vector<int>& nums) {
int n = nums.size();
// 1. 建堆(从最后一个非叶子节点向上调整)
for (int i = n / 2 - 1; i >= 0; --i) {
heapify(nums, n, i);
}
// 2. 排序(每次把最大值放最后)
for (int i = n - 1; i > 0; --i) {
swap(nums[0], nums[i]); // 把堆顶放最后
heapify(nums, i, 0); // 只对前 i 个 heapify
}
}