1. 程式人生 > >資料結構與演算法之直接插入排序

資料結構與演算法之直接插入排序

一、前言

直接插入排序(Insertion Sort)序是一種最簡單的插入排序。為簡化問題,在此我們只討論升序排序。

二、演算法思想

插入排序:每一趟將一個待排序的記錄,按照其關鍵字的大小插入到有序佇列的合適位置裡,直到全部插入完成。

假設有一組無序序列 R0, R1, ... , RN-1。

(1) 我們先將這個序列中下標為 0 的元素視為元素個數為 1 的有序序列。

(2) 然後,我們要依次把 R1, R2, ... , RN-1 插入到這個有序序列中。所以,我們需要一個外部迴圈,從下標 1 掃描到 N-1 。

(3) 接下來描述插入過程。假設這是要將 Ri 插入到前面有序的序列中。由前面所述,我們可知,插入Ri時,前 i-1 個數肯定已經是有序了。

所以我們需要將Ri 和R0 ~ Ri-1 進行比較,確定要插入的合適位置。這就需要一個內部迴圈,我們一般是從後往前比較,即從下標 i-1 開始向 0 進行掃描。

三、程式碼

def insertSort(input_list):
    if len(input_list)==0:
        return []
    sortlist=input_list
    
    for i in range(1,len(sortlist)):
        temp=sortlist[i]
        j=i-1
        while j>=0 and temp<sortlist[j]:
            sortlist[j+1]=sortlist[j]
            j-=1
        sortlist[j+1]=temp
    return sortlist

if __name__=='__main__':
    input_list=[2,5,4,8,3,9,0,1]
    print('排序前:',input_list)
    sort_list=insertSort(input_list)
    print('排序後:',sort_list)   

執行結果:


四、演算法分析

1.氣泡排序演算法的效能

2.時間複雜度

當資料正序時,執行效率最好,每次插入都不用移動前面的元素,時間複雜度為O(N)

當資料反序時,執行效率最差,每次插入都要前面的元素後移,時間複雜度為O(N^2)

所以,資料越接近正序,直接插入排序的演算法效能越好

3.演算法穩定性

直接插入排序的過程中,不需要改變相等數值元素的位置,所以它是穩定的演算法。

五、優化

因為在一個有序序列中查詢一個插入位置,以保證有序序列的序列不變,所以可以使用二分查詢,減少元素比較次數提高效率。

二分查詢是對於有序陣列而言的,假設如果陣列是升序排序的。那麼,二分查詢演算法就是不斷對陣列進行對半分割,每次拿中間元素和目標數字進行比較,如果中間元素小於目標數字,則說明目標數字應該在左側被分割的陣列中,如果中間元素大於目標數字,則說明目標數字應該在右側被分割的陣列中。

程式碼:

def BianrySearch(sortlist,end,value):
    left=0
    right=end-1
    while left<=right:
        mid=left+(right-left)//2
        if sortlist[mid]>=value:
            right=mid-1
        else:
            left=mid+1
    return left if left<end else -1

def BinaryInsertSort(input_list):
    if len(input_list)==0:
        return []
    result=input_list
    for i in range(1,len(input_list)):
        j=i-1
        temp=result[i]
        index=BianrySearch(result,i,result[i])
        if index!=-1:
            while j>=index:
                result[j+1]=result[j]
                j-=1
            result[j+1]=temp
    return result
            

if  __name__=='__main__':
    input_list=[2,5,4,8,3,9,0,1]
    print('排序前:',input_list)
    sort_list=BinaryInsertSort(input_list)
    print('排序後:',sort_list)

執行結果:


參考:http://cuijiahua.com/blog/2017/12/algorithm_2.html