1. 程式人生 > >7種排序演算法彙總

7種排序演算法彙總

排序演算法

1. 氣泡排序

  1. 平均時間複雜度O(n2) ( 最好O(n),最差O(n2) )
  2. 空間複雜度O(1)
  3. 穩定排序

程式碼如下

void BubbleSort(vector<int>& vec)
{
    if (vec.size() <= 1)
        return;

    for (int ii = 0; ii < vec.size() - 1; ++ii)
    {
        for (int jj = ii + 1; jj < vec.size(); ++jj)
        {
            if
(vec[ii]>vec[jj]) { swap(vec[ii], vec[jj]); } } } return; }

動圖效果 Alt text

2. 選擇排序

  1. 平均時間複雜度O(n2), 最優時間複雜度(n2),最壞時間複雜度(n2)
  2. 空間複雜度O(1)
  3. 不穩定排序
  4. 比較次數與序列初始化狀態無關

程式碼

void SelectSort(vector<int>& vec)
{
    if
(vec.size() <= 1) return; for (int ii = 0; ii < vec.size()-1; ++ii) { int select_val_idx = ii; for (int jj = ii + 1; jj < vec.size(); ++jj) { if (vec[jj] < vec[select_val_idx]) { select_val_idx = jj; } } swap(vec[ii], vec[select_val_idx]); } return
; }

動圖效果 這裡寫圖片描述

3. 插入排序

  1. 平均時間複雜度O(n2),最好時間複雜度O(n), 最壞時間複雜度O(n2)
  2. 空間複雜度O(1)
  3. 穩定排序
  4. 希爾排序即是多個步長的插入排序

程式碼

void InsertSort(vector<int>& vec)
{
    if (vec.size() <= 1)
        return;

    for (int ii = 1; ii < vec.size(); ++ii)
    {
        int insert_val = vec[ii];
        int jj = ii - 1;
        for ( ; jj >=0 ; --jj)
        {
            if (insert_val < vec[jj])
            {
                vec[jj + 1] = vec[jj];
            }
            else if (insert_val > vec[jj])
            {
                break;
            }

        }
        vec[jj + 1] = insert_val;
    }

    return;
}

動圖效果 Alt text

4. 快速排序

  • 平均時間複雜度O(nlogn), 最好時間複雜度O(nlogn), 最壞時間複雜度O(n2)
  • 空間複雜度O(logn)
  • 不穩定排序

程式碼

  • Partition函式用於每次確定一個元素的順序
int Partition(vector<int>&vec, int first_idx, int last_idx)
{
    if (vec.empty() || first_idx < 0 || last_idx >= vec.size() || first_idx > last_idx)
        return -1;

    int pivot = vec[first_idx];
    int ii = first_idx;

    for (int jj = first_idx + 1; jj <= last_idx; ++jj)
    {
        if (vec[jj] < pivot)
        {
            swap(vec[++ii], vec[jj]);
        }
    }
    swap(vec[first_idx], vec[ii]);

    return ii;
}
  • 真正執行快排
void QuickSortCore(vector<int>&vec, int first_idx, int last_idx)
{
    if (first_idx < last_idx)
    {
        int mid_idx = Partition(vec, first_idx, last_idx);
        QuickSortCore(vec, first_idx, mid_idx - 1);
        QuickSortCore(vec, mid_idx + 1, last_idx);
    }

    return;
}

void QuickSort(vector<int>& vec)
{
    if (vec.size() <= 1)
        return;

    int first_idx = 0;
    int last_idx = vec.size()-1;
    QuickSortCore(vec, first_idx, last_idx);

    return;
}

動圖效果 Alt text

5.歸併排序

  • 平均時間複雜度O(nlogn), 最好時間複雜度O(nlogn), 最壞時間複雜度O(nlgn)
  • 空間複雜度O(n)
  • 穩定排序

程式碼

void Merge(vector<int>& vec, int first_idx, int mid_idx, int last_idx)
{
    if (first_idx > mid_idx || last_idx < mid_idx)
        return;

    vector<int> tmp(last_idx - first_idx + 1, 0);

    int ii = first_idx, jj = mid_idx+1;
    int idx = 0;
    while (ii != mid_idx + 1 && jj != last_idx + 1)
    {
        if (vec[ii] > vec[jj])
            tmp[idx++] = vec[jj++];
        else
            tmp[idx++] = vec[ii++];
    }

    while (ii != mid_idx + 1)
    {
        tmp[idx++] = vec[ii++];
    }
    while (jj != last_idx + 1)
    {
        tmp[idx++] = vec[jj++];
    }

    for (int ii = 0; ii < tmp.size(); ++ii)
        vec[first_idx + ii] = tmp[ii];

    return;
}
void MergeSortCore(vector<int>&vec, int first_idx, int last_idx)
{
    if (first_idx > last_idx || first_idx < 0 || last_idx >= vec.size())
        return;

    if (first_idx < last_idx)
    {
        int mid_idx = first_idx + ((last_idx - first_idx) >> 1);
        MergeSortCore(vec, first_idx, mid_idx);
        MergeSortCore(vec, mid_idx + 1, last_idx);
        Merge(vec, first_idx, mid_idx, last_idx);
    }

    return;
}

void MergeSort(vector<int>& vec)
{
    if (vec.size() <= 1)
        return;

    int first_idx = 0;
    int last_idx = vec.size()-1;
    MergeSortCore(vec, first_idx, last_idx);

    return;
}

動圖效果 Alt text

6. 堆排序

  • 時間複雜度O(nlogn), O(nlogn), O(nlogn)
  • 空間複雜度 O(1)
  • 不穩定排序

程式碼

動圖效果 Alt text

7. 計數排序

Alt text