C語言數組的五種排序

冒泡排序

快速排序

選擇排序

插入排序

歸併排序

冒泡排序
冒泡排序的基本思想:不斷比較相鄰的兩個數,讓較大的元素不斷地往後移。經過一輪比較,就選出最大的數;經過第2輪比較,就選出次大的數,以此類推。對於具有N個元素的數組R[N],進行最多N-1輪比較;

/**
* 冒泡排序數組
* @param int a[] 要排序的數組
* @param int n 數組元素的個數
**/
void bubble_sort(int a[],int n){
    for(int i=0; i<n-1; i++){
        bool isSorted = true;
        for(int j=0; j<n-1-i; j++){
            if(a[j] > a[j+1]){
                isSorted = false;
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1]=temp;
            }  
        }
        if(isSorted) break;
    }
}
快速排序
快速排序是對冒泡法排序的一種改進。

快速排序算法的基本思想:定義一個變量將數組分爲左右兩個部分,左邊的數據都比該變量小,右邊的數據都比該變量大,然後將所分得的兩部分數據進行同樣的劃分,重複執行以上的劃分操作,直到所有要進行排序的數據變爲有序爲止。

代碼說明:

在第一次劃分操作中,先進行初始設置,key的值是進行劃分的基準,其值爲要劃分數組的第一個元素值,同時將low設置爲要排序數組中第一個元素的下標,將high設置爲要排序序列最後一個元素的下標。

先將下標爲high的數組元素與key進行比較,如果該元素值大於key,則high向左移動一個位置。如果該元素值小於等於key,則將該元素賦值給下標爲low所指向的數組元素,同時將low右移一個位置。

然後將low所指向的數組元素的值與key進行比較,如果該元素值小於key,則low向右移動一個位置描。如果該元素值大於等於key,則將該元素賦值給下標爲high所指向的數組元素,同時將high左移一個位置。

如此循環直到low不再小於high,劃分結束。

需要注意的是,在進行劃分的過程中,都是將掃描的值與key的值進行對比,如果小於key,那麼將該值賦值給數組中的另外一個元素,而該元素的值並沒有改變。 從圖中可以看出這一點,所以需要在劃分的最後將作爲劃分基準的key值賦值給下標爲 pos的數組元素,這個元素不再參與接下來的劃分操作。

//對數組進行劃分
int partition(int arr[], int low, int high){
    int key;
    key = arr[low];
    while(low<high){
        while(low <high && arr[high]>= key ) high--;
        if(low<high) arr[low++] = arr[high];
        while( low<high && arr[low]<=key ) low++;
        if(low<high) arr[high--] = arr[low];
    }
        arr[low] = key;
        return low;
}
 
/**
* 快速排序數組
* @param int arr[] 要排序的數組
* @param int start 序列的起始元素
* @param int end 序列的最後一個元素
**/
void quick_sort(int arr[], int start, int end){
    int pos;
    if (start<end){
        pos = partition(arr, start, end);
        quick_sort(arr,start,pos-1);
        quick_sort(arr,pos+1,end);
    }
    return;
}
選擇排序
選擇排序的基本思想:首先,選出最小的數放在第一個位置;然後,選出第二小的數放在第二個位置;以此類推,直到所有的數從小到大排序。

代碼說明:

選擇排序對大小爲N的無序數組R[N]進行排序,進行N-1輪選擇過程。第i輪選取第i小的數,並將其放在第i個位置上,然後將其與第i個數進行交換。

選擇排序是一種不穩定的排序算法,可能會打亂兩個相同數字的原有順序。

/**
* 選擇排序數組
* @param int a[] 要排序的數組
* @param int n 數組元素的個數
**/
void select_sort(int a[],int n){
    for(int i=0; i<n-1; i++){
        int min_index = i;
        for(int j=i+1; j<n; j++)
            if(a[j] < a[min_index])min_index = j;
        if( i != min_index){
            int temp = a[i];
            a[i] = a[min_index];
            a[min_index] = temp;
        }
    }
}
插入排序
插入排序的基本思想:將無序數組分爲兩部分,排序好的子數組和待插入的元素。在一個已經有序的小序列的基礎上,一次插入一個元素,直到所有元素都加入排序好數組。

/**
* 插入排序數組
* @param int a[] 要排序的數組
* @param int n 數組元素的個數
**/
void insert_sort(int a[],int n){
for(int i=1; i<n; i++){
    int j=0;
    while( (a[j]<a[i]) && (j<i)) j++;
        if(i != j){
            int temp = a[i];
            for(int k = i; k > j; k--) a[k] = a[k-1];
            a[j] = temp;
        }
    }
}
歸併排序
歸併排序也稱合併排序,其算法思想是將待排序序列分爲兩部分,依次對分得的兩個部分再次使用歸併排序,之後再對其進行合併。

代碼說明:

先對所要進行排序的序列進行分解,直到分爲單個元素爲止,然後將其進行兩兩合併。由於最終分解成單個元素,因此在合併的時候.將小數放在前面,大數放在後面,得到一個有序序列。接下來對兩個相連的有序序列進行排序,先比較有序序列中的第一個元素,將較小的元素放入臨時數組中,接着將較小元素所在數組的下一個元素與另一個數組中的較小元素比較,同樣將較小元素放入臨時數組中,依次進行,直到兩個數組的所有元素都放入臨時數組中,最後再將臨時數組的元素放入原始數組中的對應位置。

/**
* 歸併排序數組
* @param int a[] 要排序的數組
* @param int n 數組元素的個數
**/
void merge(int arr[], int low, int mid, int high){
    int i, k;
    //申請空間,使其大小爲兩個
    int *tmp = (int *)malloc((high-low+1)*sizeof(int));
    int left_low = low;
    int left_high = mid;
    int right_low = mid + 1;
    int right_high = high;
    // 比較兩個指針所指向的元素
    for(k=0; left_low<=left_high && right_low<=right_high; k++){ 
        if(arr[left_low]<=arr[right_low]) tmp[k] = arr[left_low++];
        else tmp[k] = arr[right_low++];
    }
    if(left_low <= left_high){ 
        //若第一個序列有剩餘,直接複製出來粘到合併序列尾
        //memcpy(tmp+k, arr+left_low, (left_high-left_low+l)*sizeof(int));
        for(i=left_low;i<=left_high;i++)
            tmp[k++] = arr[i];
        }
    if(right_low <= right_high){
        //若第二個序列有剩餘,直接複製出來粘到合併序列尾
        //memcpy(tmp+k, arr+right_low, (right_high-right_low+1)*sizeof(int));
        for(i=right_low; i<=right_high; i++)
            tmp[k++] = arr[i];
        }
    for(i=0; i<high-low+1; i++)
        arr[low+i] = tmp[i];
    free(tmp);
    return;
}
 
/**
* 歸併排序數組
* @param int arr[] 要排序的數組
* @param unsigned int first 數組首元素的下標
* @param unsigned int last 數組末元素的下標
**/
 
void merge_sort(int arr[], unsigned int first, unsigned int last){
    int mid = 0;
    if(first<last){
        mid = (first+last)/2; /* 注意防止溢出 */
        /*mid = first/2 + last/2;*/
        //mid = (first & last) + ((first ^ last) >> 1);
        merge_sort(arr, first, mid);
        merge_sort(arr, mid+1,last);
        merge(arr,first,mid,last);
    }
    return;
}
 
————————————————
版權聲明:本文爲CSDN博主「Noteligible」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_42322548/article/details/88317570

發佈了10 篇原創文章 · 獲贊 25 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章