十大排序(C++代碼實現)

十大排序的算法複雜度及穩定性如下:

所有代碼實現根據https://www.bilibili.com/video/av41042841動畫演示來實現,其實堆排序參考百度百科,所有代碼均已簡單測試。

#include<iostream>
#include<vector>
#include<list>
using namespace std;
// 冒泡排序
void bubble(int arr[], int len){
    for (int i = 0; i < len - 1; i++)
        if(arr[i]>arr[i+1])swap(arr[i],arr[i+1]);
}
void bubbleSort(int arr[], int len){
    for (int i = len ; i > 1; i--)
        bubble(arr, i);
}

// 選擇排序
int findMaxIndex(int arr[], int len){
    int max = arr[0], index = 0;
    for (int i = 1; i < len; i++){
        if(arr[i]>max){
            max = arr[i];
            index = i;
        }
    }
    return index;
}
void selectSort(int arr[], int len){
    for (int i = len ; i > 1; i--){
        int maxIndex = findMaxIndex(arr, i);
        swap(arr[i - 1], arr[maxIndex]);
    } 
}

// 插入排序
void insertSort(int arr[], int len){
    int t_i = 0;// 找到第一個不是升序的索引 如 3 6 7 4 找到4的索引
    while (t_i < len && arr[t_i]<arr[t_i + 1])t_i++;
    t_i ++;
    if(t_i >= len) return;
    for (int i = t_i; i < len; i++)
    {
        int t = i;
        while (t > 0 && arr[t - 1] > arr[t])
        {
            swap(arr[t], arr[t - 1]);
            t--;
        }
    }
}

// 計數排序
void calCountSort(int arr[], int len){
    int max = arr[0], min = arr[0];

    for (int i = 1; i< len; i++){
        if(arr[i] > max) max = arr[i];
        if(arr[i] < min) min = arr[i];
    }

    int t_len = max - min;
    int *temp = new int[t_len + 1];
    for (int i = 0; i < t_len + 1; i++)
        temp[i] = 0;
    
    for (int i = 0; i < len; i++)
        temp[arr[i] - min]++;
    
    int newIndex = 0;
    for (int i = 0; i <= t_len; i++)
        while (temp[i]--)
            arr[newIndex++]= i + min;
    
    delete[] temp;
    temp = 0;
    
}

// 基數排序
void radixSort(int arr[], int len){
    //  index:當前的基數(個、十、百...) max: 數組中最大的數
    int index = 1, max = arr[0];
    for (int i = 1; i < len; i++)
        if(arr[i] > max)max = arr[i];
    
    vector<vector<int>> radix(10,vector<int>());
    while(index < max){
        for (int i = 0; i < len; i++)
        {
            int t = arr[i] / index;// 開始先對個位求基數,隨後到百位千位...
            int yushu = t % 10;//基數就是桶的索引
            radix[yushu].push_back(arr[i]);
        }
        // 每次都對所有數據合併
        int newIndex = 0;
        for (int i = 0; i < radix.size(); i++)
        {
            for(auto x : radix[i])
                arr[newIndex++] = x;
            radix[i].clear();
        }
        index *= 10;//基數向前增加
    }
    radix.clear();
}

// 快速排序
int partial(int arr[], int l, int r){
    // 以右邊爲基準, index記錄基準的索引,最後和l交換
    int p = arr[r], index = r;
    while (l < r)
    {
        while (l<r&&arr[l] <= p)l++;
        while (l<r&&arr[r] >= p)r--;
        swap(arr[l], arr[r]);
    }
    swap(arr[index], arr[l]);  
    return l;
}
void quickSort(int arr[], int l, int r){
    if(l >= r)return;
    int p = partial(arr, l, r);
    quickSort(arr, l, p - 1);
    quickSort(arr, p + 1, r);
}

//桶排序
void bucketSort(int arr[], int len){
    
    int max = arr[0], min = arr[0];
    for (int i = 1; i < len; i++){
        if(max<arr[i])max = arr[i];
        if(min>arr[i])min = arr[i];
    }
    // 桶的個數 = max /10 - min/10 + 1
    int bucketSize = max /10 - min/10 + 1;
    vector<list<int>> buckets(bucketSize + 1, list<int>());   
    int range = (max - 2 + 1) / bucketSize;//每個桶容納的數

    for (int i = 0; i < len; i++)
    {
        int index = (arr[i] - min) / range;// 得到待插入桶的索引
        if(!buckets[index].size())// 如果桶內沒有數據 直接插入
            buckets[index].insert(buckets[index].begin(), arr[i]);
        else{// 如果桶有數據 找到合適的插入位置 插入
            auto begin = buckets[index].begin();
            while (*begin < arr[i] && begin != buckets[index].end())begin++;
            buckets[index].insert(begin, arr[i]);
        }
    }
    // 把所有桶內的數據提取出來放到原數組
    int newIndex = 0; 
    for (int i = 0; i < buckets.size(); i++)
        for(auto x : buckets[i])
            arr[newIndex++] = x;
    //清空所有桶數據
    buckets.clear();
}

// 希爾排序
void shellSort(int arr[], int len){
    int gap = len / 2;
    while (gap)
    {
        for (int i = gap; i < len; i++)
        {
            int j = i,t = arr[j];
            while (j - gap >= 0 && arr[j - gap] > t)
            {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = t;    
        }
        gap /= 2;
    }
}

// 歸併排序
// 合併兩個有序數組
void merge(int arr[], int temp[], int l, int m, int r){
    int i = l, j = m + 1, k = l;
    while (i <= m && j <= r)
    {
        if(arr[i] < arr[j])
            temp[k++] = arr[i++];
        else temp[k++] = arr[j++];
    }
    while (i <= m)
        temp[k++] = arr[i++];
    while (j <= r)
        temp[k++] = arr[j++];
    for (i = l; i <= r; i++)
        arr[i] = temp[i];
}
void mergeSort(int arr[], int temp[], int l, int r){
    if(l >= r)return;
    int mid = l + (r - l) / 2;
    mergeSort(arr, temp, l, mid);
    mergeSort(arr, temp, mid + 1, r);
    merge(arr, temp, l, mid, r);
}

// 堆排序
void maxHeapify(int arr[], int start, int end) 
{
    //cout<<start<<": ";
    //建立父節點指標和子節點指標
    int dad = start;// dad:4
    // son 和 son + 1 分別是兩個子結點
    int son = dad * 2 + 1;// son:9
    while (son <= end)  //若子節點指標在範圍內才做比較
    {    
        if (son + 1 <= end && arr[son] < arr[son + 1]) //先比較兩個子節點大小,選擇最大的
            son++;
        if (arr[dad] > arr[son]){ //如果父節點大於子節點代表調整完畢,直接跳出函數
            // cout<<"return"<<endl;
            return;
        }
        else  //否則交換父子內容再繼續子節點和孫節點比較
        {
            swap(arr[dad], arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
    
    // for (int i = 0; i < 10; i++)
    // {
    //     cout<<arr[i]<<" ";
    // }
    // cout<<endl;
}
 
void heapSort(int arr[], int len) 
{
    //初始化,i從最後一個父節點開始調整
    for (int i = len / 2 - 1; i >= 0; i--)// 4 3 2 1 0
        maxHeapify(arr, i, len - 1);// maxHeapify(arr, 4, 9)
    //先將第一個元素和已經排好的元素前一位做交換,再從新調整(剛調整的元素之前的元素),直到排序完畢
    for (int i = len - 1; i > 0; i--) 
    {
        swap(arr[0], arr[i]);
        maxHeapify(arr, 0, i - 1);
    }
}
int main(){
    int arr[10] = {588, 392, 898, 115, 306, 62, 909, 902, 789, 234};
    int temp[10] = {0};
    mergeSort(arr, temp, 0, 9);
    for (int i = 0; i < 10; i++)
    {
        cout<<arr[i]<<" ";
    }
    system("pause");
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章