1.快速排序
快速排序使用分治方法,比基准值小的数字放到基准值左面,比基准值大的放到基准值右面;然后分别对基准值左侧、右侧分别使用快速排序;基准值可以随意选择,一般选择第一个或者最后一个数字
- 选择基准值
- 比基准值小的放到左边,比基准值大的放到右边
- 基准值放到空出的位置
- 分别对左边和右边使用快速排序
int quick_sort2(vector<int>& nums, int start, int end) {
if (start >= end) return start;
int left = start, right = end;
int tmp = nums[start];//基准值,此时nums[start] 空出,可以放比基准值小的数
//循环里面先寻找比基准值小的数,放到此位置
while(left < right) {
while (left < right && nums[right] >= tmp) {//寻找小于base的位置
right--;
}
if (right > left) {
nums[left] = nums[right];
left++;
}
while (left < right && nums[left] <= tmp) {//寻找大于base的位置
left++;
}
if (left < right) {
nums[right] = nums[left];
}
}
nums[left] = tmp;
quick_sort2(nums, start, left - 1); //左边,区间[start, left-1]
quick_sort2(nums, left + 1 ,end); //右边,区间[left+1, end]
return left;
}
void quick_sort(vector<int>& nums) {
quick_sort2(nums, 0, nums.size() - 1);
}
2 归并排序
归并排序也是采用分治的思想,对于要排序的数组从中间分成左右两部分,对左右两部分递归使用归并排序;左右两部分排完序以后,按大小合并在一起
边界条件:只剩下一个数时直接返回
1.划分为左右两部分
2.分别对左右两部分分别使用递归排序
3.左右两部分合并在一起
//合并有序区间[left, mid] [mid+1, right]
void merge_two_array(vector<int>& nums, int left, int mid, int right, vector<int>&tmp_res) {
int i = left, j = mid + 1;
int tmp_idx = left;
while (i <= mid && j <= right) {
if (nums[i] <= nums[j]) {
tmp_res[tmp_idx] = nums[i];
tmp_idx += 1;
i += 1;
}else {
tmp_res[tmp_idx] = nums[j];
tmp_idx += 1;
j += 1;
}
}
while (i <= mid) {
tmp_res[tmp_idx] = nums[i];
tmp_idx += 1;
i += 1;
}
while (j <= right) {
tmp_res[tmp_idx] = nums[j];
tmp_idx += 1;
j += 1;
}
//调整nums,两个数组下标是连续的
for (int i = left; i <= right; i++) {
nums[i] = tmp_res[i];
}
}
void merge_sort2(vector<int>& nums, int left, int right, vector<int>& tmp_res) {
if (left >= right) {//只有一个数字时,已经有序直接返回
return;
}
int tmp_mid = (left + right)/2;
merge_sort2(nums, left, tmp_mid, tmp_res);//左边使用归并排序[left, mid]
merge_sort2(nums, tmp_mid+1, right, tmp_res);//右边使用归并排序[mid, right]
merge_two_array(nums, left, tmp_mid, right, tmp_res);//左右两边合并
}
void merge_sort(vector<int>& nums) {
int n = (int)nums.size();
vector<int> tmp_res(n);
merge_sort2(nums, 0, n-1, tmp_res);
}
3.选择排序
每次从数组中选择出最小的数字放到已排序的最后边
void select_sort(vector<int>& nums) {
int n = (int) nums.size();
for (int i = 0; i < n; i++) {
//选出最小的数字
int min = i;
for (int j = i + 1; j < n; j++) {
if (nums[j] < nums[min]) {
min = j;
}
}
//放到排好序的最后边
int tmp = nums[i];
nums[i] = nums[min];
nums[min] = tmp;
}
}
4 冒泡排序
void bubble_sort(vector<int>& nums) {
int n = (int)nums.size();
for (int i = 0; i < n - 1; i++) {//控制已排好序的个数
// for (int j = 0; j < n - i - 1; j++) {//大的数下沉
// if(nums[j] > nums[j+1] ) {
// //std::swap(nums[j], nums[j+1]);
// int tmp = nums[j];
// nums[j] = nums[j+1];
// nums[j+1] = tmp;
// }
// }
for(int j = n - 1; j > i; j--) {//小的数上浮
if(nums[j] < nums[j-1] ) {
int tmp = nums[j];
nums[j] = nums[j-1];
nums[j-1] = tmp;
}
}
}
}
5.插入排序
对左侧已排好序的数组,查找当前数的插入位置,同时后移大于当前的数
void insertion_sort(vector<int>& nums){
int len =(int) nums.size();
for(int i = 1; i < len; i++){
int key = nums[i];
int j=i-1;
while((j>=0) && (key < nums[j])){
nums[j+1]=nums[j];//后移
j--;
}
nums[j+1]=key;//插入位置
}
}