zoukankan      html  css  js  c++  java
  • 各种简单排序算法模版

    基于比较的排序(复杂度下界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];
        }
    }
    
    本人菜鸡一枚!
    如有错误还请大佬们多多指教!
  • 相关阅读:
    蓝牙搜索
    Log4cpp介绍及使用
    单独卸载vs2010帮助文档HelpView之后的独立安装教程
    C++Builder RAD Studio XE, UTF-8 String 转换为 char * 字符串的最简单方式, 常用于sqlite3开发
    vs2012 MSDN帮助文档离线包下载安装方法
    关于OBJ/LIB格式,我以前有个总结
    关于C++ const 的全面总结
    在 C++Builder 工程里调用 DLL 函数
    c++builder调用VC的dll以及VC调用c++builder的dll
    C++Builder及VC的库相互调用
  • 原文地址:https://www.cnblogs.com/watchphone/p/13397134.html
Copyright © 2011-2022 走看看