1. 程式人生 > 其它 >常見的排序演算法的簡單實現

常見的排序演算法的簡單實現

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N];

/**演算法名稱:直接插入排序
 * 時間複雜度:最好情況:O(n),最壞情況:O(n^2), 平均情況:O(n^2)
 * 空間複雜度:O(1)
 * 穩定性:穩定
 **/
void insert_sort()
{
    for (int i = 0; i < n; i ++ )
    {
        int t = q[i], j = i;
        while (j >= 0 && q[j - 1] > t)
        {
            q[j] = q[j - 1];
            j -- ;
        }
        q[j] = t;
    }
}
/**演算法名稱:折半插入排序
 * 時間複雜度:最好情況:O(n),最壞情況:O(n^2), 平均情況:O(n^2)
 * 空間複雜度:O(1)
 * 穩定性:穩定
 **/
void binary_search_insert_sort()
{
    for (int i = 0; i < n; i ++ )
    {
        if (q[i - 1] < q[i]) continue;
        int t= q[i];
        int l = 0, r = i - 1;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (q[mid] <= t) l = mid + 1;
            else r = mid;
        }
        int j = i;
        while (j > l)
        {
            q[j] = q[j - 1];
            j -- ;
        }
        q[l] = t;
    }
}
/**演算法名稱:折半插入排序
 * 時間複雜度:最好情況:O(n),最壞情況:O(n^2), 平均情況:O(n^2)
 * 空間複雜度:O(1)
 * 穩定性:穩定
 **/
void bubble_sort()
{
    for (int i = 0; i < n; i ++ )
    {
        int flag = true;
        for (int j = n - 1; j > i; j -- )
        {
            if(q[j] < q[j - 1])
            {
                flag = false;
                swap(q[j], q[j - 1]);
            }
        }
        if (flag) break;
    }
}
/**演算法名稱:簡單選擇排序
 * 時間複雜度:最好情況:O(n^2),最壞情況:O(n^2), 平均情況:O(n^2)
 * 空間複雜度:O(1)
 * 穩定性:不穩定 如:2 2 1 --swap(q[0],q[3])--> 1 2 2 如果穩定最後一個2應該是在第二個二的前面但實際上不會所以不穩定
 **/
void select_sort()
{
    for (int i = 0; i < n - 1; i ++ )
    {
        int t = q[i], tmp = i;
        for (int j = i; j < n; j ++ )
        {
            if (q[j] < t)
            {
                t = q[j];
                tmp = j;
            }
        }
        swap(q[i], q[tmp]);
    }
}
/**演算法名稱:shell排序 公差d 分組內部插入排序
 * 時間複雜度:O(n^3/2)
 * 空間複雜度:O(1)
 * 穩定性:不穩定
 **/
void shell_sort()
{
    for (int d = n / 3; d; d = d == 2 ? 1 : d / 3)
    {
        for (int start = 0; start < d; start ++ )
        {
            for (int i = start + d; i < n; i += d)
            {
                int t = q[i], j = i;
                while (j > start && q[j - d] > t)
                {
                    q[j] = q[j - d];
                    j -= d;
                }
                q[j] = t;
            }
        }
    }
}

/**演算法名稱:快速排序
 * 時間複雜度:最好情況:O(nlogn),最壞情況:O(n^2), 平均情況:O(nlogn)
 * 空間複雜度:O(logn)
 * 穩定性:不穩定
 **/
void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

/**演算法名稱:桶排序
 * 時間複雜度:O(n + m) n為元素個數 m為元素最大值
 * 空間複雜度:O(m)
 * 穩定性:穩定
 **/
int s[N], w[N];
void bucket_sort(){
    //統計每個桶裡面應該有多少元素,即小於和等於在該元素左邊的個數
    for(int i = 0 ;i < n ; i++)   s[q[i]]++;
    //求所有桶的字首和(迴圈到數值的最大範圍)
    for(int i = 0 ; i < N ; i++)  s[i] += s[i - 1];
    /*把每個元素放到對應的位置上,一定要從後往前放(穩定),先放到
    輔助數組裡面,防止產生讀寫的衝突*/
    for(int i = n - 1 ; i >= 0 ; i --)  w[-- s[q[i]]] = q[i];
    //排完序之後,把序列複製到原陣列中去
    for(int i = 0 ; i <  n ; i++)  q[i] = w[i];
}

int main()
{
    scanf("%d", &n);
    
    for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
    
    //insert_sort();
    //binary_search_insert_sort();
    //bubble_sort();
    //select_sort();
    shell_sort();
    
    for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);
}