堆排序
要学习堆排序,首先要学习堆的向下调整算法,因为要用堆排序,你首先得建堆,而建堆需要执行多次堆的向下调整算法。
堆的向下调整算法(使用前提):
若想将其调整为小堆,那么根结点的左右子树必须都为小堆。
若想将其调整为大堆,那么根结点的左右子树必须都为大堆。
向下调整算法的基本思想(以建大堆为例):
1.从根结点处开始,选出左右孩子中值较大的孩子。
2.让大的孩子与其父亲进行比较。
若大的孩子比父亲还大,则该孩子与其父亲的位置进行交换。并将原来大的孩子的位置当成父亲继续向下进行调整,直到调整到叶子结点为止。
若大的孩子比父亲小,则不需处理了,调整完成,整个树已经是大堆了。
图片示例:
class Solution {
void AdjustDown(vector<int>& nums, int n, int root) {
int parent = root;
int child = root * 2 + 1;
while (child < n) {
if (child + 1 < n&&nums[child + 1] > nums[child]) {
child++;
}
if (nums[child] < nums[parent]) {
swap(nums[child], nums[parent]);
parent = child;
child = parent * 2 + 1;
}
else {
break;
}
}
}
void BuildHeap(vector<int>& nums, int size) {
for (int i = size / 2 - 1; i >= 0; i--) {
AdjustDown(nums, size, i);
}
}
void HeapSort(vector<int>nums, int size) {
BuildHeap(nums, size);
for (int i = size - 1; i > 0; i--) {
swap(nums[0], nums[i]);
AdjustDown(nums, size, i);
}
}
};