三分鐘看懂插入排序演算法

weixin_34249678發表於2019-01-20

今天我們還來聊一聊另一種排序演算法,插入排序。

插入排序,顧名思義,插入操作是整個排序過程中的重要步驟。

首先有必要說明一點,一種特定的演算法都是基於某種特定的資料結構的,我們這裡的演算法都是指資料存放於陣列結構中的。

先來用人話給插入排序來個定義:

把陣列分成已排序和未排序兩個區間,以陣列第一個元素當做已排序區間,剩下的即被當做未排序區間,每次都從未排序區間中找出一個元素來和已排序區間中的元素比較,並插入到已排序區間中的合適位置,直到未排序區間元素為 0 。

如果這個定義還沒看懂,沒關係,我再舉一個實際的例子,應該能幫你更好的理解。

新學期體育課,老師通常會按身高高矮來安排同學站佇列。首先班上的同學都隨便站成一列,老師會把較矮的同學從佇列中拉出來,讓其站到佇列前面,這樣其實就把原本無序的佇列分成有序和無序兩個區間了,前面的都是有序的,後面的都是待排序的。

老師每次從後面拉一個同學出來都會和前面已經排好序的同學比較身高,然後再插入到合適的位置。

在這裡,老師是聰明的,看一眼就能知道某個同學該站在哪個位置,但是計算機就不能了,計算機只能一個一個的去比較了,而且只能把第一個元素當做已排序區間,第二個及以後的元素當做未排序區間。

為了更好的理解,這裡建議大家認為這個老師很死板,從第二個同學開始和第一個同學比較身高,如果第二個同學比第一個同學還要矮,那就把第二個同學插入到第一個同學的前面,即站第一個位置,這時候第一和第二個同學就是一個新的已排序區間了。

接下來再讓第三個同學依次和第一、第二個同學比較身高,並插入到合適的位置。後面的同學都按照同樣的方式來比較並插入,到最後就是一個從矮到高的有序佇列了。

插入排序其實主要有比較和插入兩個操作,先通過比較找到合適的插入位置,由於在陣列中插入一個元素是需要移動其後面的所有元素的,因此在依次比較的同時就需要後移空出一個位置來,找到合適的位置後,直接插入就行。

再來分析下插入排序的演算法複雜度,簡單來說,插入排序有兩個巢狀迴圈,所以時間複雜度為 O(n^2),由於不需要額外的儲存空間,所以其空間複雜度為 O(1),而且插入排序不會破壞陣列中兩個相同元素原有的順序,因此插入排序是一種穩定的排序演算法。

下面我分別用 python 和 php 實現了插入排序演算法,程式碼中有詳細的註釋說明。

# -*- coding: utf-8 -*-


def insertSort(arr):
    lens = len(arr)
    if lens <= 1:
        return 

    for i in range(1,lens): #先遍歷未排序區間元素,從第二個元素開始
        value = arr[i] #獲取未排序區間中的第一個元素        
        #開始找插入位置
        for j in range(i,-1,-1): #遍歷已排序區間元素,從尾部開始           
            if value < arr[j-1]: #拿未排序區間中的第一個元素和已排序區間中的元素依次比較,直到找到適合插入的位置
                arr[j] = arr[j-1] #往後移動元素,留出插入位置
            else:
                break
        arr[j] = value #將未排序區間拿出來的元素插入到合適的位置

    return arr


arr = [9,824,4,5,2,1,7,8]

print(insertSort(arr))
複製程式碼
//php實現插入排序演算法

function insertSort($arr){
    $len = count($arr);

    if ($len <= 1){
        return false;
    }

    for ($i=1; $i < $len; $i++) { 
        $val = $arr[$i];
        $j = $i-1;

        for ($j; $j >= 0; $j--) {            
            if($val < $arr[$j]){
                $arr[$j+1] = $arr[$j];              
            }else{
                break;
            }
        }
        $arr[$j+1] = $val;
    }
    return($arr);
}


$arr = [4,6,7,3,22,1,88,456,5];
print_r(insertSort($arr));
複製程式碼

相關文章