排序(2):直接插入排序

1、前言
直接插入排序(Insertion Sort)序是一種最簡單的插入排序。爲簡化問題,咱們下面只討論升序排序。算法

2、算法思想
插入排序:每一趟將一個待排序的記錄,按照其關鍵字的大小插入到有序隊列的合適位置裏,直到所有插入完成。 數組

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

(1) 咱們先將這個序列中下標爲 0 的元素視爲元素個數爲 1 的有序序列。優化

(2) 而後,咱們要依次把 R1, R2, ... , RN-1 插入到這個有序序列中。因此,咱們須要一個外部循環,從下標 1 掃描到 N-1 。spa

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

因此咱們須要將Ri 和R0 ~ Ri-1 進行比較,肯定要插入的合適位置。這就須要一個內部循環,咱們通常是從後往前比較,即從下標 i-1 開始向 0 進行掃描。blog

代碼排序

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

def insertSort(input_list):
    if len(input_list) == 0:
        return []
    sorted_list = input_list

    for i in range(1, len(sorted_list)):
        temp = sorted_list[i]
        j = i - 1
        while j >=0 and temp < sorted_list[j]:
            sorted_list[j + 1] = sorted_list[j]
            j -= 1
        sorted_list[j + 1] = temp
    return sorted_list

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

3、算法分析
一、直接插入排序的算法性能隊列

clipboard.png

二、時間複雜度ip

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

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

因此,數據越接近正序,直接插入排序的算法性能越好。

三、空間複雜度

由直接插入排序算法可知,咱們在排序過程當中,須要一個臨時變量存儲要插入的值,因此空間複雜度爲 1 。

四、算法穩定性

直接插入排序的過程當中,不須要改變相等數值元素的位置,因此它是穩定的算法。

4、優化

由於在一個有序序列中查找一個插入位置,以保證有序序列的序列不變,因此可使用二分查找,減小元素比較次數提升效率。

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

代碼

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

def BinarySearch(input_list, end, value):
    left = 0
    right = end - 1
    while left <= right:
        middle = left + (right - left) // 2
        if input_list[middle] >= value:
            right = middle - 1
        else:
            left = middle + 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]
        insert_index = BinarySearch(result, i, result[i])
        if insert_index != -1:
            while j >= insert_index:
                result[j + 1] = result[j]
                j -= 1
            result[j + 1] = temp
    return result


if __name__ == '__main__':
    input_list = [6, 4, 8, 9, 2, 3, 1]
    print('排序前:', input_list)
    sorted_list = insertSort(input_list)
    print('排序後:', sorted_list)
相關文章
相關標籤/搜索