1. 程式人生 > >插入排序,C語言實現

插入排序,C語言實現

插入排序是穩定排序,時間複雜度最低為O(n),最高為O(n^2),平均為O(n^2)。

 

插入排序是將陣列分為兩部分,一部分已經排好序,另一部分未排好序,每次從未排好序的部分取第一個元素插入到已經排好序的部分正確的位置,如此迴圈n-1次。

就好像你手裡有十張牌,左手有一張,右手有九張。每次從右手的牌中取最左邊的一張插入到左手的牌裡,右手的牌插完了,排序也完成了。

 

編寫程式碼要點:

  1. 時間複雜度是O(n^2),意味著有雙重迴圈。外面大迴圈代表插入的輪次,因為一開始左手有一張牌,所以只需要插入n-1次即可,也就是每次插入都從左手牌末尾元素的下標+1開始。
  2. 內層迴圈是從後方前反向遍歷,因為要插入到正確的位置,需要給這個待插入的元素挪一個位置,所以在待插入的位置後面的所有元素都要整體後移一個位置,覆蓋掉待插入元素初始的位置,然後把待插入的元素放置在空出來的位置即可。因為在元素整體後移給待插入元素挪位置的時候會覆蓋掉待插入元素原本的位置,所以需要用一個元素來儲存待插入的元素。

 

插入排序程式碼如下:

#include <stdio.h>

void insertSort(int arr[], int n) {
    int i, j;
    int currentElement;
    // 前i個元素有序,初始情況只有一個有序組,也就是陣列的第一個元素,故i=1
    for (i = 1; i < n; ++i) {
        currentElement = arr[i];    // 儲存當前要插入的元素,因為之後移動陣列元素的時候會覆蓋掉當前的元素
        // 從後向前遍歷,找到插入位置,也就是最後一個比待插入的元素小的元素
        
// 從待插入的前一個元素開始遍歷,所以j=i-1,遍歷到末尾,也就是陣列開頭,i=0 for (j = i - 1; j >= 0; --j) { if (arr[j] > currentElement) { arr[j + 1] = arr[j]; } else { break; // 找到了插入元素的位置,結束迴圈 } } // 此時arr[j]是<currentElement的,它並沒有被移動,也沒有留出空缺,空缺在它身後
// 故把currentElement賦值給arr[j]身後的空缺,也就是arr[j+1] arr[j + 1] = currentElement; } } int main() { int i = 0; int arr[10] = {5, 2, 3, 8, 1, 2, 6, 9, 3, 7}; insertSort(arr, 10); for (i = 0; i < 10; ++i) { printf("%d ", arr[i]); } return 0; }