Leetcode 912 数组排序
给你一个整数数组 nums,请你将该数组升序排列。
方法一: 快速排序
参考: https://blog.csdn.net/wthfeng/article/details/78037228
基本思想:将基点放入他正确的位置,将数组划分为两份: 大于基点的,小于基点的。然后对两份分别进行递归,直至所有的点都位于合适的位置。
- 确定出归条件,当区间只含有一个元素时,即:不用继续排序了。 所以出归条件为: low >= high.
- 先将右边界向左扫描,遇到小于基点的元素,停止扫描
- 再将左边界向右扫描,遇到大于基点的元素,停止扫描
- 交换这时的左右边界元素
- 继续重复上述2-5,直至左右边界相遇,则跳出循环,交换这时的右边界和基点元素。
- 然后在对左半边进行递归排序
- 最后对右半边进行递归排序
class Solution {
public:
void quickSort(vector<int>& nums,int low, int high){
if(low>=high){
return;
}
int base = nums[low];
int i = low; // [l, i-1] <= base
int j = high; // [j+1, high] >=base
while(i<j){
while(base <= nums[j] && i <j){
j--;
}
while(base >= nums[i] && i <j){
i++;
}
swap(nums[i],nums[j]);
}
swap(nums[low],nums[j]);
quickSort(nums,low,j-1);
quickSort(nums,j+1,high);
}
vector<int> sortArray(vector<int>& nums) {
if(nums.size()==0){
return nums;
}else{
int low = 0;
int high = nums.size()-1;
quickSort(nums, low, high);
return nums;
}
}
};
改进方法:
1.在最后几个元素时,采用插入排序
2.快速排序最差情况,退化了O(n^2). 数组有序时。这时采用随机标定点
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int low = 0;
int high = nums.size() - 1;
quickSort(nums,low,high);
return nums;
}
void quickSort(vector<int>& nums, int low, int high){
if(low>=high){
return;
}
int i = low;
int j = high;
// 随机选取标定点
swap(nums[low],nums[rand()%(high-low+1)+low]);
int base = nums[low];
while(i < j){
while(nums[j]>=base && i < j){
j--;
}
while(nums[i]<=base && i < j){
i++;
}
swap(nums[i],nums[j]);
}
swap(nums[low],nums[j]);
quickSort(nums, low, j-1);
quickSort(nums, j+1, high);
}
};
三路快排
当数组中含有大量重复元素时,三路快排优势明显。
基本思想:
将数组分成3部分:
- 小于v,其区间为[l+1, lt]
- 等于v, 其区间为[lt+1,i-1]
- 大于v,其区间为[gt,r]
当arr[i] <v时, swap(arr[lt+1], arr[i]); lt++; i++;
当arr[i] = v 时,i++;
当arr[i] >v 时,swap(arr[gt-1], arr[i]); gt–;
直到i >= gt 时停止遍历,swap(arr[lt], arr[l]).
然后在对非等于v的部分进行递归三路排序。
class Solution {
public:
void quickSort(vector<int>& arr, int l, int h){
if(l>=h){
return;
}
int j = l; // [l+1, l] < v . 现在是空集
int k = h+1; // [k, h] > v . 现在是空集
int v = arr[l];
int i = j+1; // [j+1, i-1] = v . 现在是空集
while(i<k){
if(arr[i]<v){
swap(arr[i],arr[j+1]);
i++;
j++;
}else if(arr[i] == v){
i++;
}else{
swap(arr[k-1],arr[i]);
k--;
}
}
swap(arr[j],arr[l]);
quickSort(arr, l, j-1);
quickSort(arr,k,h);
}
void sortColors(vector<int>& nums) {
int l = 0;
int h = nums.size()-1;
quickSort(nums, l, h);
}
};
注意,j, k ,i 的初始赋值
需要使三个区间为空集