十大排序算法

排序算法

排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性
冒泡排序 O(n^2) O(n) O(n^2) O(1) In-place 稳定
选择排序 O(n^2) O(n^2) O(n^2) O(1) In-place 不稳定
插入排序 O(n^2) O(n) O(n^2) O(1) In-place 稳定
希尔排序 O(n(logn)^2) O(nlogn) O(n(logn)^2) O(1) In-place 不稳定
归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) Out-place 稳定
快速排序 O(nlogn) O(nlogn) O(n^2) O(logn) In-place 不稳定
堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) In-place 不稳定
计数排序 O(n + k) O(n + k) O(n + k) O(k) Out-place 稳定
桶排序 O(n + k) O(n + k) O(n^2) O(n ) Out-place 稳定
基数排序 O(n * k) O(n * k) O(n * k) O(n + k) Out-place 稳定
image-20220327143935170

冒泡排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N];

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);

    for (int i = 0; i < n - 1; i ++ )
        for (int j = 0; j < n - i - 1; j ++)
            if (q[j] > q[j + 1])
                swap(q[j], q[j + 1]);

    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);    

    return 0;
}
  • 优化版本
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N];

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);
        
    for (int i = 0; i < n - 1; i ++)
    {
        bool flag = false;
        for (int j = 0; j < n - 1 - i; j ++)
            if (q[j] > q[j + 1])
            {
                swap(q[j], q[j + 1]);
                flag = true;
            }
        if (!flag) break;
    }
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
        
    return 0;
}

选择排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N];

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);
        
    for (int i = 0; i < n - 1; i ++)
    {
        int minvIndex = i;
        for (int j = i + 1; j < n; j ++)
            if (q[j] < q[minvIndex])
                minvIndex = j;
        swap(q[minvIndex], q[i]);
    }
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
        
    return 0;
}

插入排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, preIndex, curVal;
int q[N];

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);
    
    for (int i = 1; i < n; i ++)
    {
        preIndex = i - 1;
        curVal = q[i];
        while (preIndex >= 0 && q[preIndex] > curVal)
        {
            q[preIndex + 1] = q[preIndex];
            preIndex --;
        }
        q[preIndex + 1] = curVal;
    }
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
        
    return 0;

}

希尔排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N];

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);
        
    for (int gap = n / 2; gap > 0; gap /= 2)
    {
        for (int i = gap; i < n; i ++)
        {
            int j = i - gap, cur = q[i];
            while (j >= 0 && cur < q[j])
            {
                q[j + gap] = q[j];
                j -= gap;
            }
            q[j + gap] = cur;
        }
    }
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
        
    return 0;
}

归并排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N], temp[N];

void merge_sort(int q[], int l, int r)
{
    if (l >= r) return;
    int mid = l + r >> 1;  
    merge_sort(q, l, mid), merge_sort(q, mid + 1, r);
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
    {
        if (q[i] < q[j]) temp[k ++] = q[i ++];
        else temp[k ++] = q[j ++];
    }
    while (i <= mid) temp[k ++] = q[i ++];
    while (j <= r) temp[k ++] = q[j ++];
    for(int i = l, j = 0; i <= r; i ++, j ++)
        q[i] = temp[j];
    
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);
        
    merge_sort(q, 0, n - 1);
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
        
    return 0;
}

快速排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int q[N];

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

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
        scanf("%d", &q[i]);
        
    quick_sort(q, 0, n - 1);
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
    
    return 0;
}

堆排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, m, len;
int h[N];

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

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++)
        scanf("%d", &h[i]);
    
    len = n;
        
    for (int i = n / 2; i >= 1; i --)
        down(i);
        
    while (m --)
    {
        printf("%d ", h[1]);
        h[1] = h[len --];
        down(1);
    }
    
    return 0;
}

计数排序

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010, M = 10001;

int n, m;   // m 就是存储元素的最大值
int q[N], bucket[M];


int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
		scanf("%d", &q[i]);
         m = max(m, q[i]);
    }
        
    for (int i = 0; i < n; i ++)
        bucket[q[i]] ++;
    
    for (int i = 0, j = 0; i <= m; i ++)
        while (bucket[i] > 0)
        {
            q[j ++] = i;
            bucket[i] --;
        }
    
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
        
    return 0;

}

计数排序必须先确定排序元素的最大值,然后开辟额外的空间来存储每个元素出现的次数。

桶排序

#include <iostream>
#include <algorithm>
#include <limits.h>

using namespace std;

const int N = 100010;

int n;
int q[N];

int main()
{
    int maxv = INT_MIN, minv = INT_MAX;
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
        scanf("%d", &q[i]);
        maxv = max(maxv, q[i]);
        minv = min(minv, q[i]);
    }
    
    // 计算桶的数量
    int bucketNum = (maxv - minv) / n + 1;
    vector<vector<int>> bucketArr(bucketNum);
    
    // 将每个元素放入桶
    for (int i = 0; i < n; i ++)
    {
        int num = (q[i] - minv) / n;
        bucketArr[num].push_back(q[i]);
    }
    
    // 对每个桶进行排序
    for (int i = 0; i < bucketNum; i ++)
        sort(bucketArr[i].begin(), bucketArr[i].end());
        
    // 将桶中的元素放入原数组
    for (int i = 0, k = 0; i < bucketNum; i ++)
        for (int j = 0; j < bucketArr[i].size(); j ++)
            q[k ++] = bucketArr[i][j];
            
    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);
    
    return 0;

}

基数排序

#include <iostream>
#include <algorithm>
#include <limits.h>

using namespace std;

const int N = 100010;

int n;
int q[N], bucket[10], output[N];

int main()
{
    cin >> n;
    int maxv = INT_MIN;
    for (int i = 0; i < n; i ++)
    {
        scanf("%d", &q[i]);
        maxv = max(maxv, q[i]);
    }

    for (int exp = 1; maxv / exp > 0; exp *= 10)
    {
        for (int i = 0; i < n; i ++)    
            bucket[(q[i] / exp) % 10] ++;

        for (int i = 1; i < 10; i ++)
            bucket[i] += bucket[i - 1];

        for (int i = n - 1; i >= 0; i --)
        {
            output[bucket[(q[i] / exp) % 10] - 1] = q[i];
            bucket[(q[i] / exp) % 10] --;
        }

        for (int i = 0; i < n; i ++)
            q[i] = output[i];
    }

    for (int i = 0; i < n; i ++)
        printf("%d ", q[i]);

    return 0;
}

基数排序的代码有点问题!

posted @ 2022-06-08 09:57  Maple~  阅读(21)  评论(0编辑  收藏  举报