堆排序
Tips:
- 建立堆的时候从最后一个父节点开始,这样越往上走,其实是和大值比较,这样才能找出最大值;
- 建立好大堆之后,我们需要将堆顶(最大值)和最后一个元素交换,这样数组中的最后一个元素就是最大值,同时,由于现在不满足大顶堆,我们需要重新将这个堆大顶化。记当前的堆顶为T,很显然调整后的堆顶为T,T的左孩子,T的右孩子中的最大的一个,记住,这个过程要一直持续下去使得整个堆满足大顶堆的性质;
- 我们是把数组按顺序逻辑抽象成一棵树,但本质还是一个数组;
class Solution {
private:
void swap(int& a, int& b) {
int t = a;
a = b;
b = t;
}
void maxHeapify(vector<int>& nums, int begin, int len) {
// has child
// left child 2i+1
// right child 2i+2
while((begin<<1)+1 <= len) {
int lchild = 2 * begin + 1;
int rchild = 2 * begin + 2;
int large;
// rchild may not exist
if(nums[lchild] > nums[begin]) {
large = lchild;
} else {
large = begin;
}
// check the right
if(rchild <= len && nums[rchild] > nums[large]) {
large = rchild;
}
if(large != begin) {
swap(nums[large], nums[begin]);
begin = large;
} else {
break;
}
}
}
void heapSort(vector<int>& nums) {
// build maxHeap first
int len = nums.size() - 1;
for(int i = len/2; i >=0; i--) {
maxHeapify(nums, i, len);
}
// now we get a maxHeap and then we sort it
swap(nums[0], nums[len]);
for(int i = 1; i < len; i++) {
maxHeapify(nums, 0, len-i);
swap(nums[0], nums[len-i]);
}
}
public:
vector<int> sortArray(vector<int>& nums) {
heapSort(nums);
return nums;
}
};