数据结构与算法 | 青训营笔记

82 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第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)

  1. 确定分界点 q[l] q[(l + r)/2] q[r] 随机
  2. 调整区间 :第一个区间<=x, 第二个区间>=x
  3. 递归处理左右两端

暴力实现方法:

  1. 开两个数组 a[],b[]
  2. 扫描q[l~r] q[i]<=x x插入a[]中 q[i]>x x插入b[]中
  3. a[]->q[],b[]->q[]

优美实现做法

  1. 两指针一左一右 i指向大于x的数放在右半边,j指向小于x放左半边
  2. 一次遍历后分为两部分左边都小于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小的数

快排思想

  1. 确定分界点 q[l] q[(l + r)/2] q[r] 随机
  2. 调整区间 :第一个区间<=x, 第二个区间>=x
  3. 递归处理左右两端
#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;    
}