幾種排序算法比較


排序對比圖

一、交換排序:

1、冒泡算法:

​核心:相鄰比大小,交換

遍歷length-1遍

每遍的子遍歷遍歷length-i遍(第1遍時,i=2)

Bubble_Sort(int &array[]){
​    for(i = 1; i<length-1,i++){
        for(j = 0; j<length-i; j++){             //第1遍時,i為2
            if array[j] >array[j+1]{
                  int help = array[j];
                  array[j] = array[j+1];
                  array[j+1] = help;
           }
        }        
    }
}

.
.

2、快速排序:

核心:將序列排好,分解為子序列,子序列繼續排列,排列完的子序列繼續分自身的子序列
特點:在同一個數組上排序,無需格外數組,不斷排序

(1)首先設定一個分界值,通過該分界值將數組分成左右兩部分。
(2)將大於或等於分界值的數據集中到數組右邊,小於分界值的數據集中到數組的左邊。此時,左邊部分中各元素都小於或等於分界值,而右邊部分中各元素都大於或等於分界值。
(3)然后,左邊和右邊的數據可以獨立排序。對於左側的數組數據,又可以取一個分界值,將該部分數據分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的數組數據也可以做類似處理。
(4)重復上述過程,可以看出,這是一個遞歸定義。通過遞歸將左側部分排好序后,再遞歸排好右側部分的順序。當左、右兩個部分各數據排序完成后,整個數組的排序也就完成了。

void split(int &array,[] int start, int end){
    int key = quicksort(start, end);
    split(stat, key-1);
    split(key+1, end );
}

void quicksort(int &array[], int start, int end){
    key = array[start];
    
    while(start != end && start != end+1){
        while (array[end] >= key && start<end) 
            end--;
        if(start < end) 
            array[start++] = array[end];                //引用后再加1;
        while(array[start] > key && start <end) 
            start++;
        if(start < end)
            array[end-- ] = array[start];               //引用后再減1;
    }
        array[start] = key;                             //退出時start == end, 講基准數放入坑中 
        return key;
}

.
.

更加簡潔的代碼:

void quick_sort(int s[], int l, int r){
    if (l < r)
    {
        //Swap(s[l], s[(l + r) / 2]); //將中間的這個數和第一個數交換 參見注1
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while(i < j && s[j] >= x) // 從右向左找第一個小於x的數
                j--;  
            if(i < j) 
                s[i++] = s[j];
            
            while(i < j && s[i] < x) // 從左向右找第一個大於等於x的數
                i++;  
            if(i < j) 
                s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s, l, i - 1); // 遞歸調用 
        quick_sort(s, i + 1, r);
    }
}

//  此代碼,  
    作者:MoreWindows
    原文:https://blog.csdn.net/morewindows/article/details/6684558 


.
.

二、插入排序

​思想:

  • 遍歷 length-1遍“子遍歷”
  • 每遍“子遍歷”遍歷 i 遍
insertion_sort(int &array[]){
    int i,j,help = 0;
    for(i = 0; i<length-1; i++){
        j = i;                            //第1遍時,j=1;
        while(j > 0){
            if(array[j] < array[j-1]){
                help = array[j];
                array[j] = array[j-1];      
                array[j-1] = array[j];
            }     
        }
    }
}

.
.

三、選擇排序:

思想:

  • 從小到大排序,從左往右遍歷,每次遍歷,flag = “子遍歷的首位數下標”,“子遍歷”每次找到比flag小的數,就記錄其下標flag = 下標;
  • 子遍歷結束,子遍歷的首位數 與 數組flag標記位置交換
Selection_sort(int &array[]){
    for(int i = 0; i<array.length-2; i++ ){
        int  flag = i-1;
        for(int j = i; j<length-2; j++){                              //第1遍時,j = 1;
            if(array[flag] > array[j]) flag = j;
        }
        int help = array[i-1];
        array[i-1] = array[flag];
        array[flag] = help;    
    }
}

.
.

四、歸並排序

思想

  • 歸並算法與快速排序相反,是把順序的子序列給合並起來,再排序
  • 需要借助格外數組
  • 穩定

//排序獲取的兩個子數組
void Sort(int &array[],int start,int middle,int end){  
    if()
    int help[] = new int[];
    int i =start,j = middle+1,z = 0;
    
    while(i != middle+1 && j != end+1;){           //比較數據並且交換
        if(array[i] <= array[j]){
            help[z] = array[i];
            i++;
        }
        else{
            help[z] = array[j];
            j++;
        }

        z++;
    }
    
    if(i != middle+1){                              //help數組追加數組后面較大的數據
        while(i != middle+1){
            help[z] = array[i];
            i++;
        }
    }
    else if(j != end+1){
         while(i != middle+1){
            help[z] = array[j];
            j++;
        }
    }
    
    z = 0;                                          //help數組導入array數組
    while(start != end+1){
        array[start] = help[z];
        start++;
    }
}
//開始歸並排序函數;遞歸合並子數組
//若數組數為偶數,中間數偏左
void Merge(int &array[],int start,int end){         
    int middle = (end + start)/2;                                 
    Merge(&array,start, middle);                     //數組數為偶數,左數組數比右數數組多1
    Merge(&array,middle+1, end);
    Sort(&array,start, middle,end)
}     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM