直接插入排序是一種最簡單的插入排序。
這裡我們主要學習直接插入公升序排序。
1.什麼是插入排序:
每一趟將乙個待排序的記錄,按照其關鍵字的大小插入到有序佇列的合適位置裡,直到全部插入完成。
例子:在打撲克牌的時候:
你手裡有一張5,
再摸到一張4,比5小,插到5前面,
又摸到一張6,比5大,插到5後面,
再摸到一張7,比6大,插到6後面
…這就是典型的直接插入排序,每次將乙個新資料插入到有序佇列中的合適位置裡。
2.演算法思想:
假設我們現在有一組待排序的序列 d0,d1,d2,…,nn-1
(1)我們先將這個序列下標為0的元素d0視為個數為1的有序序列
(2)然後,我們將d1,d2,…,nn-1插入到這個有序序列中。所以,我們需要乙個外部迴圈,從下標 1 掃瞄到 n-1 。
(3)假設這是要將 di 插入到前面有序的序列中,由前面所述,我們可知,插入di時,前 i-1 個數肯定已經是有序了。
所以我們需要將di 和d0 ~ di-1 進行比較,確定要插入的合適位置。這就需要乙個內部迴圈,我們一般是從後往前比較,即從下標 i-1 開始向 0 進行掃瞄。
3.python3**實現:
# -*- coding: utf-8 -*-
"""created on wed jul 10 11:44:36 2019
@author: zqq
"""def
insertsort
(input_list)
: n =
len(input_list)
# 計算待排序序列長度
if n <=1:
# 已有序,或為空,直接返回
return input_list
else
:# 第一層迴圈表示插入的遍數
for i in
range(1
,n):
# i取 1,2,3,..., n-1
# 當前待插入的元素
current = input_list[i]
# 已經有序元素的索引
pre_index = i -
1while pre_index >=
0and input_list[pre_index]
> current:
# 當 比較元素 > 當前元素, 則把比較元素後移
input_list[pre_index +1]
= input_list[pre_index]
# 往前選擇下乙個比較元素
pre_index -=
1# 當 比較元素 < 當前元素,或不滿足pre_index>=0,則將 當前元素 插入其後面
input_list[pre_index +1]
= current
print
(input_list)
return input_list
input_list =[6
,4,8
,9,2
,3,1
]print
('排序前:'
, input_list)
sorted_list = insertsort(input_list)
print
('排序後:'
, sorted_list)
4.演算法分析:
插入排序的適用場景:乙個新元素需要插入到一組已經是有序的陣列中,或者是一組基本有序的陣列排序。
(1)比較性:排序時元素之間需要比較,所以為比較排序
(2)穩定性:從**我們可以看出只有比較元素大於當前元素,比較元素才會往後移動,所以相同元素是不會改變相對順序,穩定排序。
(3)時間複雜度:插入排序同樣需要兩次循壞乙個乙個比較,故時間複雜度為o(n^2)
(4)空間複雜度:只需要常數個輔助單元,所以空間複雜度為o(1)
(5)複雜性:簡單
注:當資料正序時,執行效率最好,每次插入都不用移動前面的元素,時間複雜度為o(n)。
當資料反序時,執行效率最差,每次插入都要前面的元素後移,時間複雜度為o(n^2)。
所以,資料越接近正序,直接插入排序的演算法效能越好。
平均情況:o(n^2)
5.演算法優化:
因為在乙個有序序列中查詢乙個插入位置,以保證有序序列的序列不變,所以可以使用二分查詢,減少元素比較次數提高效率。
二分查詢是對於有序陣列而言的,假設如果陣列是公升序排序的,那麼,二分查詢演算法就是不斷對陣列進行對半分割,每次拿中間元素和目標數字進行比較,如果中間元素小於目標數字,則說明目標數字應該在右側被分割的陣列中,如果中間元素大於目標數字,則說明目標數字應該在左側被分割的陣列中。
# -*- coding: utf-8 -*-
"""created on wed jul 10 15:46:21 2019
@author: zqq
"""~
~~python
# -*- coding:utf-8 -*-
defbinarysearch
(input_list, end, value)
: left =
0 right = end -
1while left <= right:
middle = left +
(right - left)//2
if input_list[middle]
>= value:
right = middle -
1else
: left = middle +
1return left if left < end else-1
defbinaryinsertsort
(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
input_list =[6
,4,8
,9,2
,3,1
]print
('排序前:'
, input_list)
sorted_list = binaryinsertsort(input_list)
print
('排序後:'
, sorted_list)
資料結構 直接插入排序
直接插入排序 include include typedef struct int elem int length sqlist void initsqlist sqlist l int i printf 請輸入元素個數 scanf d l length l elem int malloc size...
資料結構 直接插入排序
直接插入排序 將待插入子串行元素逐步插入到有序序列的執行過程。設有一待排序序列s 其中是有序的,是無序的,要把後面無需的元素,乙個乙個的插入到前面有序的集合中去。如下面的序列可以分為兩個子串行 和 初始序列 75 88 68 92 88 62 77 96 80 72 第一次排序 75 88 68 9...
資料結構 直接插入排序
將乙個記錄插入到已排好序的序列中,從而得到乙個新的有序序列 將序列的第乙個資料看成是乙個有序的子串行,然後從第二個記錄逐個向該有序的子串行進行有序的插入,直至整個序列有序 可以選擇不同的方法在已經排好序資料表中尋找插入位置。根據查詢方法不同,有多種插入排序方法,下面要介紹的是直接插入排序。設待排序的...