各种简单排序算法模版

基于比较的排序(复杂度下界nlogn)

冒泡排序

时间复杂度 最坏O(n^2) 平均O(n^2) 最好O(n)
空间复杂度 O(1)
稳定

void bubbleSort(int *a, int n) {
	for (int i = n - 1, t; i; i = t) {
        t = i;
        for (int j = 0; j + 1 <= i; j++)
            if (a[j] > a[j + 1]) {
                swap(a[j], a[j + 1]);
                t = j;
            }
    }
}

选择排序

时间复杂度 最坏O(n^2) 平均O(n^2) 最好O(n^2)
空间复杂度 O(1)
稳定

void selectionSort(int *a, int n) {
    for (int i = 0; i < n - 1; i++) {
        int mini = i;
        for (int j = i + 1; j < n; j++)
            if (a[j] < a[mini]) mini = j;
        //swap(a[mini], a[i]); //不稳定
        int t = a[mini]; //稳定
        for (int j = mini; j > i; j--)
            a[j] = a[j - 1];
        a[i] = t;
    }
}

插入排序

时间复杂度 最坏O(n^2) 平均O(n^2) 最好O(n)
空间复杂度 O(1)
稳定

void insertionSort(int *a, int n) {
    for (int i = 1; i < n; i++) {
        int t = a[i], j;
        /*for (j = i - 1; j >= 0; j--)
            if (a[j] > t) a[j + 1] = a[j];
            else break;*/
      	for (j = i - 1; j >= 0 && a[j] > t; j--)
        	a[j + 1] = a[j];
        a[j + 1] = t;
    }
}

希尔排序

时间复杂度 最坏O(n^2) 平均O(n^1.3) 最好O(n) ?
空间复杂度 O(1)
不稳定

void shellSort(int *a, int n) { //性能一般,不经常用
    int gap = 1;
    while (gap < n / 3) {
        gap = gap * 3 + 1;
    }
    for (; gap; gap = gap / 3) //枚举间隔
        for (int i = 0; i < gap; i++) //枚举每一组
            for (int j = i + gap; j < n; j += gap) { //插入排序
                int t = a[j], k;
                for (k = j - gap; k >= 0 && a[k] > t; k -= gap)
                    a[k + gap] = a[k];
                a[k + gap] = t;
            }
}

归并排序

时间复杂度 最坏O(nlogn) 平均O(nlogn) 最好O(nlogn)
空间复杂度 top down vector: O(n + logn) list: O(logn)
bottom up vector: O(n) list: O(1)
稳定

void mergeSort(int *a, int l, int r) {
    if (l >= r) return;
    int mid = l + r >> 1;
    
    mergeSort(a, l, mid), mergeSort(a, mid + 1, r);
    
    int *A = a + l, *B = a + mid + 1;
    int lc = mid - l + 1, lb = r - mid;
    int C[lc];
    memcpy(C, A, sizeof(int) * lc);
    
    int i = 0, j = 0, k = 0;
    while (k < lc && j < lb) {
        if (C[k] <= B[j]) A[i++] = C[k++];
        else A[i++] = B[j++];
    }
    while (k < lc) A[i++] = C[k++];
}

快速排序

时间复杂度 最坏O(n^2) 平均O(nlogn) 最好O(nlogn)
空间复杂度 最坏O(n) 平均O(logn) 最好O(logn)
不稳定

void qSort(int *a, int l, int r) {
    if (l == r) return;
    int i = l - 1, j = r + 1, p = a[l + r >> 1];
    while (i < j) {
        while (a[++i] < p);
        while (a[--j] > p);
        if (i < j) swap(a[i], a[j]);
    }
    qSort(a, l, j), qSort(a, j + 1, r);
}

堆排序

时间复杂度 最坏O(nlogn) 平均O(nlogn) 最好O(nlogn)
空间复杂度 递归实现O(logn) or 迭代实现O(1)
不稳定

void down(int *h, int u, int n) {
    int t = u;
    if (2 * u <= n && h[2 * u] > h[t]) t = 2 * u;
    if (2 * u + 1 <= n && h[2 * u + 1] > h[t]) t = 2 * u + 1;
    if (t != u) {
        swap(h[t], h[u]);
        down(h, t, n);
    }
}

void heapSort(int *a, int n) {
    for (int i = n / 2; i; i--) down(a, i, n);
    while (n) {
        swap(a[1], a[n--]);
        down(a, 1, n);
    }
}

不基于比较的排序

计数排序

时间复杂度、空间复杂度与有关
稳定?

void countingSort(int *a, int n) {
    const int N = 100000;
    int c[N] = {0};
    for (int i = 0; i < n; i++) c[a[i]]++;
    for (int i = 0, t = 0; i < N; i++) //0 <= a[i] <= N - 1
        while (c[i]--) a[t++] = i;
}

桶排序

是一种思想。
基本思路是:
1.将待排序元素划分到不同的桶,先扫描一遍序列求出最大值maxV和最小值minV,设桶的个数为 k ,则把区间[minV, maxV]均匀划分成k个区间,每个区间就是一个桶。将序列中的元素分配到各自的桶。
2.对每个桶内的元素进行排序。可以选择任意一种排序算法。
3.将各个桶中的元素合并成一个大的有序序列。
假设数据是均匀分布的,则每个桶的元素平均个数为n/k 。假设选择用快速排序对每个桶内的元素进行排序,那么每次排序的时间复杂度为 O(n/klog(n/k)) 。总的时间复杂度为O(n) + k * O(n/klog(n/k)) = O(n + nlog(n/k)) = O(n + nlogn - nlogk) 。当 k 接近于 n 时,桶排序的时间复杂度就可近似认为是 O(n) 的。即桶越多,时间效率就越高,而桶越多,所需空间就越大。

基数排序

时间复杂度 最坏O(n) 平均O(n) 最好O(n) 但常数较大
空间复杂度 O(n) ?
稳定

void radixSort(int *a, int n) {
    for (int i = 0; i < 10; i++) {
        vector<int> b[10];
        for (int j = 0; j < 10; j++) b[j].clear();
        for (int j = 0; j < n; j++)
            b[get(a[j], i)].push_back(a[j]);
        for (int j = 0, l = 0; j < 10; j++)
            for (int k = 0; k < b[j].size(); k++)
                a[l++] = b[j][k];
    }
}
posted @ 2020-07-29 14:53  watchphone  阅读(188)  评论(0编辑  收藏  举报