1.快排
左闭右闭的二分写法
void quick_sort(vector<int> &nums, int l, int r) {
if (l + 1 >= r) {
return;
}
int first = l, last = r - 1, key = nums[first];
while (first < last){
//一轮
while(first < last && nums[last] >= key) {//从后往前找比枢轴小的元素
--last;
}
nums[first] = nums[last];//找到后填补到原来的枢轴位置
while (first < last && nums[first] <= key) {//从前往后找比枢轴大的元素
++first;
}
nums[last] = nums[first];//填补last的位置
}
nums[first] = key;
quick_sort(nums, l, first);
quick_sort(nums, first + 1, r);
}
快排可改进为快速选择算法,用来在未排序的数组中寻找第K小/大的元素,思路:选择一个元素作为基准来对元素进行分区,将小于和大于基准的元素分在基准左边和右边的两个区域。不同的是,快速选择并不递归访问双边,而是只递归进入一边的元素中继续寻找。这降低了平均时间复杂度,从O(n log n)至O(n),不过最坏情况仍然是O(n2)。
class Solution {//找第K大元素
public:
int quickSelect(vector<int>& nums,int l,int r){
int i=l+1,j=r;//注意i初始为l+1
while(true){
while(i<r && nums[i]<=nums[l])//找大于枢轴的元素
++i;
while(l<j && nums[j]>=nums[l])//找小于枢轴的元素
--j;
if(i>=j)//比枢轴大的元素在比枢轴小的元素的右侧,不用调换位置
break;
swap(nums[i],nums[j]);//比枢轴大的元素在比枢轴小的元素的左侧,调换位置
}
swap(nums[l],nums[j]);//交换j元素到枢轴位置
return j;//返回枢轴位置
}
int findKthLargest(vector<int>& nums, int k) {//算法主体
int l=0,r=nums.size()-1,target=nums.size()-k;
while(l<r){//二分
int mid=quickSelect(nums,l,r);//得到划分
if(mid==target)
return nums[mid];
if(mid<target)
l=mid+1;
else
r=mid-1;
}
return nums[l];
}
};
2.归并排序
void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp) {
if (l + 1 >= r) {
return;
}
// divide
int m = l + (r - l) / 2;
merge_sort(nums, l, m, temp);
merge_sort(nums, m, r, temp);
// conquer
int p = l, q = m, i = l;
while (p < m || q < r) {
if (q >= r || (p < m && nums[p] <= nums[q])) {
temp[i++] = nums[p++];
}
else {
temp[i++] = nums[q++];
}
}
for (i = l; i < r; ++i) {
nums[i] = temp[i];
}
}
3.插入排序
void insertion_sort(vector<int> &nums, int n) {
for (int i = 0; i < n; ++i) {
for (int j = i; j > 0 && nums[j] < nums[j-1]; --j) {
swap(nums[j], nums[j-1]);
}
}
}
4.冒泡排序
void bubble_sort(vector<int> &nums, int n) {
bool swapped;
for (int i = 1; i < n; ++i) {
swapped = false;
for (int j = 1; j < n - i + 1; ++j) {
if (nums[j] < nums[j-1]) {
swap(nums[j], nums[j-1]);
swapped = true;
}
}
if (!swapped) {
break;
}
}
}
5.选择排序
void selection_sort(vector<int> &nums, int n) {
int mid;
for (int i = 0; i < n - 1; ++i) {
mid = i;
for (int j = i + 1; j < n; ++j) {
if (nums[j] < nums[mid]) {
mid = j;
}
}
swap(nums[mid], nums[i]);
}
}
调用格式
void sort() {
vector<int> nums = {1,3,5,7,2,6,4,8,9,2,8,7,6,0,3,5,9,4,1,0};
vector<int> temp(nums.size());
sort(nums.begin(), nums.end());
quick_sort(nums, 0, nums.size());
merge_sort(nums, 0, nums.size(), temp);
insertion_sort(nums, nums.size());
bubble_sort(nums, nums.size());
selection_sort(nums, nums.size());
}