1、快速排序:O(NlogN),不稳定。
基本思路: 1.1、设置两个变量 left、right。 1.2、整个数组找基准正确位置,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面。
在数据随机情况下,默认数组的第一个数为基准数据,赋值给key,即key = array[left]。
- 因为默认数组的第一个数为基准,所以从后面开始向前搜索(right),找到第一个小于key的array[right],(循环条件是array[right] >= key;结束时 array[right] < key)。
- 此时从前面开始向后搜索(left++),找到第一个大于key的array[left](循环条件是 array[left] <= key;结束时array[left] > key)。
找到第一对i ,j,然后swap。
循环 1-3 步骤,直到 left >= right,该位置就是基准位置。把基准数据赋给当前位置。 1.3、第一趟找到的基准位置,作为下一趟的分界点。 1.4、递归调用分界点前和分界点后的子数组排序,重复1.2、1.3、1.4的步骤。
写法1
void QuickSort(vector<int>& nums, int l, int r)
{
if(nums.size() == 0)return;
if(l >= r)return;
int i = l, j = r;
while(i < j)
{
while(i < j && nums[j] >= nums[l]) j--;
while(i < j && nums[i] <= nums[l]) i++;
swap(nums[i], nums[j]);
}
swap(nums[i], nums[l]);
QuickSort(nums, l, i - 1);
QuickSort(nums, i + 1, r);
}
写法2
int partition(vector<int>&arr, int l, int r)
{
if(arr.size() == 0 || l < 0 || r< 0)return -1;
int key = arr[l];
int i = l, j = r;
while (i < j) {
while (i < j && arr[j] >= key) j--;
while (i < j && arr[i] <= key) i++;
swap(arr[i], arr[j]);
}
swap(arr[i], key);
return i;
}
void Quicksort(vector<int>& arr, int l,int r)
{
if (l >= r) return;
int i = partition(arr, l ,r);
Quicksort(arr, l, i - 1);
Quicksort(arr, i + 1, r);
}
2、归并排序:O(N*logN) /O(N) 稳定
从局部有序到整体有序。具体来说,就是可以将原数组进行分割(分治),分别进行运算(递归),实现局部有序,然后通过一个外排进而实现整体有序
分治到只有一个数字,两两比较,借助辅助数组,a和b中的较小值填入辅助数组,并且右移,直到其中一个指针遍历了其所在的子数组的全部元素,结束并将另外的数组的剩余元素全部拷贝到辅助数组。
#include<iostream>
#include<vector>
using namespace std;
void mergeSort(vector<int>& nums, int l, int mid, int r) {
vector<int>tmp(r - l + 1, 0);
int i = l;
int j = mid + 1;
int index = 0;
while (i <= mid && j <= r) {
if (nums[i] <= nums[j]) {
tmp[index++] = nums[i++];
}
else {
tmp[index++] = nums[j++];
}
}
while (i <= mid) {
tmp[index++] = nums[i++];
}
while (j <= r) {
tmp[index++] = nums[j++];
}
for (int k = 0; k < tmp.size(); k++) {
nums[k + l] = tmp[k];
}
}
void merge(vector<int>& nums, int l, int r) {
if (l >= r)return;
int mid = l + ((r - l) >> 1);
merge(nums, l, mid);
merge(nums, mid + 1, r);
mergeSort(nums, l, mid, r);
}
int main()
{
vector<int>nums = {7,3,2,6,0,1,5,4};
int n = nums.size();
merge(nums, 0, n - 1);
for (int i = 0; i < n; i++)
{
cout << nums[i] << " ,";
}
return 0;
}
稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 仍然在 b 的前面,则为稳定排序。 冒泡+插入+归并稳定。
|