这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记。
1.插入排序
插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。
void InsertSort(int A[],int n){
int i,j,temp;
for(i=1;i<n;i++){
if(A[i]<A[i-1]){
temp=A[i];
for(j=i-1;j>=0&&A[j]>temp;--j){
A[j+1]=A[j];
}
A[j+1]=temp;
}
}
}
2.快速排序
思想:分治 最坏O(n^2) 平均O(nlogn)
- 确定分界点 q[l] q[(l + r)/2] q[r] 随机
- 调整区间 :第一个区间<=x, 第二个区间>=x
- 递归处理左右两端
暴力实现方法:
- 开两个数组 a[],b[]
- 扫描q[l~r] q[i]<=x x插入a[]中 q[i]>x x插入b[]中
- a[]->q[],b[]->q[]
优美实现做法
- 两指针一左一右 i指向大于x的数放在右半边,j指向小于x放左半边
- 一次遍历后分为两部分左边都小于x右边都大于x
void quick_sort(int l, int r){
if(l >= r) return;
int i = l - 1, j = r + 1, x = a[l + r >> 1];
while(i < j){
while(a[++i] < x);
while(a[--j] > x);
if(i < j) swap(a[i], a[j]);
}
quick_sort(l, j); quick_sort(j + 1, r);
}
快速选择算法
选择第k小的数
快排思想
- 确定分界点 q[l] q[(l + r)/2] q[r] 随机
- 调整区间 :第一个区间<=x, 第二个区间>=x
- 递归处理左右两端
#include<iostream>
using namespace std;
const int maxn = 1e5 + 100;
int a[maxn], n, k;
int quick_sort(int l, int r, int k){
if(l >= r) return a[l];
int i = l - 1, j = r + 1, x = a[l + r >> 1];
while(i < j){
while(a[++i] < x);
while(a[--j] > x);
if(i < j) swap(a[i], a[j]);
}
int s1 = j - l + 1;
if(k <= s1)quick_sort(l, j, k);
else quick_sort(j + 1, r, k - s1);
}
int main()
{
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
int x = quick_sort(0, n - 1, k);
printf("%d\n", x);
return 0;
}