插入排序法的兩種實現
阿新 • • 發佈:2020-12-23
插入排序法的實現,這裡做了兩種實現(思想是一樣的):
- 一種是從前向後排,把後面的無序序列,插入到前面的有序序列
- 一種是從後向前排,把前面的無序序列,插入到後面的有序序列
廢話不多說,直接上程式碼,下面程式碼已經經過除錯,拿過去可以直接執行:
#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @File : sort_by_insertion.py @Contact : [email protected] @MTime : 2020-12-21 17:21 @Author: buweiqiang @Version: 1.0 @Desciption: 插入排序法思想:假設已經有一個有序序列,將未排序的陣列,逐個個的插入到有序序列的合適位置 ''' import random import time def sort_forward(array: list): ''' 正序插入:假設第一位是有序序列,從第二位開始迭代,依次將後面的數字,插入到前面的有序序列 方法:假設第一位i=0是有序序列,從i+1開始,每次取有序序列後面位置的一個數j=i+1,將這個數與前面的有序序列(長度為i+1)向前逐個比較,如果比前面的小,就與之交換(即永遠將小的數插入到大數的前面),如果不比前面的小,就可以中止退出本次迴圈 :param array: 未排序的陣列 :return: 無 ''' n = len(array) for i in range(n - 1): # 從第二位開始,第一輪過後,前二位是有序序列,第二輪後,前三位是有序序列,以次類推,直到整個陣列排序完成 j = i + 1 swap_count = 0 # 記錄交換次數 while j > 0: if array[j] < array[j - 1]: temp = array[j] array[j] = array[j - 1] array[j - 1] = temp j -= 1 swap_count += 1 else: # 因為前面已經是有序序列,所以只要出現了一個數不比後面的小,就可以中止比較了,這點與比氣泡排序要好,不用每次都遍歷到末尾 break print(f'round {i + 1}, swap_count={swap_count}: {array}') def sort_backward(array: list): ''' 倒序插入:假設倒數第一位是有序序列,從倒數第二位開始迭代,依次將前面的數字,插入到後面的有序序列 方法:假設最後一位n-1是有序序列,i=1~n,從n-1-i開始,每次取有序序列前面位置的一個數j=n-1-i,將這個數與後面的有序序列(長度為i)逐個比較,如果比後面的大,就與之交換(即永遠將大的數插入到小數的後面),如果不比後面的大,就可以中止退出本次迴圈 :param array: 未排序的陣列 :return: 無 ''' n = len(array) for i in range(1, n): # 從倒數第二位開始,第一輪過後,倒數二位是有序序列,第二輪後,倒數三位是有序序列,以次類推,直到整個陣列排序完成 j = n - 1 - i swap_count = 0 while j < n - 1: if array[j] > array[j + 1]: temp = array[j] array[j] = array[j + 1] array[j + 1] = temp j += 1 swap_count += 1 else: # 因為後面已經是有序序列,所以只要出現了前一個數不比後面的大,就可以中止比較了,這點與比氣泡排序要好,不用每次都遍歷到末尾 break print(f'round {i + 1}, swap_count={swap_count}: {array}') if __name__ == "__main__": array = [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10] # 如需做效能測試,把陣列變長和迴圈次數加大即可 # array = [random.randint(0, 1000) for i in range(20)] print(array) # 正排 start_time = time.time() for i in range(1): sort_forward(array.copy()) end_time = time.time() duration = end_time - start_time print(f'duration of forward insertion: {duration}') # 倒排 start_time = time.time() for i in range(1): sort_backward(array.copy()) end_time = time.time() duration = end_time - start_time print(f'duration of backward insertion: {duration}')
貼一下輸出:
/usr/local/bin/python3.7 /Users/boweqiang/xxw/AutotestCornerstone/common/sort_by_insertion.py [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10] round 1, swap_count=0: [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10] round 2, swap_count=0: [5, 7, 8, 5, 9, 3, 2, 10, 1, 13, 10] round 3, swap_count=2: [5, 5, 7, 8, 9, 3, 2, 10, 1, 13, 10] round 4, swap_count=0: [5, 5, 7, 8, 9, 3, 2, 10, 1, 13, 10] round 5, swap_count=5: [3, 5, 5, 7, 8, 9, 2, 10, 1, 13, 10] round 6, swap_count=6: [2, 3, 5, 5, 7, 8, 9, 10, 1, 13, 10] round 7, swap_count=0: [2, 3, 5, 5, 7, 8, 9, 10, 1, 13, 10] round 8, swap_count=8: [1, 2, 3, 5, 5, 7, 8, 9, 10, 13, 10] round 9, swap_count=0: [1, 2, 3, 5, 5, 7, 8, 9, 10, 13, 10] round 10, swap_count=1: [1, 2, 3, 5, 5, 7, 8, 9, 10, 10, 13] duration of forward insertion: 8.797645568847656e-05 round 2, swap_count=1: [5, 7, 8, 5, 9, 3, 2, 10, 1, 10, 13] round 3, swap_count=0: [5, 7, 8, 5, 9, 3, 2, 10, 1, 10, 13] round 4, swap_count=1: [5, 7, 8, 5, 9, 3, 2, 1, 10, 10, 13] round 5, swap_count=1: [5, 7, 8, 5, 9, 3, 1, 2, 10, 10, 13] round 6, swap_count=2: [5, 7, 8, 5, 9, 1, 2, 3, 10, 10, 13] round 7, swap_count=3: [5, 7, 8, 5, 1, 2, 3, 9, 10, 10, 13] round 8, swap_count=3: [5, 7, 8, 1, 2, 3, 5, 9, 10, 10, 13] round 9, swap_count=4: [5, 7, 1, 2, 3, 5, 8, 9, 10, 10, 13] round 10, swap_count=4: [5, 1, 2, 3, 5, 7, 8, 9, 10, 10, 13] round 11, swap_count=3: [1, 2, 3, 5, 5, 7, 8, 9, 10, 10, 13] duration of backward insertion: 8.20159912109375e-05 Process finished with exit code 0