一.堆排序向上调整法实现堆排序
逻辑含义:视频链接 理解堆heapfiy(向上调整)的含义就很容易去理解代码
代码实现:
#include <bits/stdc++.h>
using namespace std;
void buildMaxHeap(vector<int>& nums) {
int n = nums.size();
for (int i = (n - 1 - 1) / 2; i >= 0; i--) {//从n-1的父亲节点开始遍历,然后依次自右向左再向上heapfiy 其中n-1为第n个元素的下标为n-1
maxHeapify(nums, i, n);
}
}
void maxHeapify(vector<int>& nums, int i, int n) {
while (i * 2 + 1 < n) {//当至少有一个孩子
// 代表当前 i 节点的左右儿子;
// 超出数组大小则代表当前 i 节点为叶子节点,不需要移位
int lSon = 2 * i + 1;
int rSon = 2 * i + 2;
int large = i;
if (lSon < n && nums[lSon] > nums[i]) large = lSon;
if (rSon < n && nums[rSon] > nums[large]) large = rSon;
if (large != i) {
swap(nums[i], nums[large]);
// 迭代判断对应子节点及其儿子节点的大小关系
i = large;
} else {
break;
}
}
}
vector<int> sortArray(vector<int>& nums) {
// heapSort 堆排序
int n = nums.size();
// 将数组整理成大根堆
buildMaxHeap(nums);
for (int i = n - 1; i >= 1; --i) {
// 依次弹出最大元素,放到数组最后,当前排序对应数组大小 - 1
swap(nums[0], nums[i]);
--n;
maxHeapify(nums, 0, n);
}
return nums;
}
二.快速排序向上调整法实现堆排序
讲解:视频链接 在1:40:00左右荷兰国旗问题 ------左神
更进一步理解:快速排序详解及应用 | labuladong 的算法笔记
代码实现:
#include <bits/stdc++.h>
using namespace std;
void swap(int& a, int& b) {
if (a == b) {
return;
}
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
vector<int> partition(vector<int>& nums, int L, int R) {
srand(time(0));
int m = rand() % (R - L + 1) + L;
m=nums[m];
int p1 = L, p2 = R, i = L;
while (i <= p2) {
if (nums[i] < m) {
swap(nums[i], nums[p1]);
p1++;
i++;
} else if (nums[i] > m) {
swap(nums[i], nums[p2]);
p2--;
} else {
i++;
}
}
return vector<int> { p1-1, p2+1 };
}
void quickSort(vector<int>& nums, int L, int R) {
if (L >= R) return;
vector<int> m = partition(nums, L, R);
quickSort(nums, L, m[0]);
quickSort(nums, m[1], R);
}
三.归并排序
讲解:归并排序详解及应用 | labuladong 的算法笔记
代码实现:
#include <bits/stdc++.h>
using namespace std;
vector<int> temp;
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
temp.resize(n);
sort(nums,0,n-1);
return nums;
}
void sort(vector<int>& nums,int left,int right){
if(right<=left) return;
int mid = left+(right-left)/2;
sort(nums,left,mid);
sort(nums,mid+1,right);
merge(nums,left,mid,right);
}
void merge(vector<int>& nums,int left,int mid,int right){
for(int i=left;i<=right;i++) temp[i] = nums[i];
int i = left,j = mid+1,p=left;
while(p<=right){
if(i==mid+1) nums[p++] = temp[j++];
else if(j==right+1) nums[p++] = temp[i++];
else if(temp[i]<=temp[j]) nums[p++] = temp[i++];
else if(temp[i]>temp[j]) nums[p++] = temp[j++];
}
}