資料結構 Python實現直接插入排序(4)

2021-09-25 03:36:35 字數 3888 閱讀 9434

直接插入排序是一種最簡單的插入排序

這裡我們主要學習直接插入公升序排序。

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...

資料結構 直接插入排序

將乙個記錄插入到已排好序的序列中,從而得到乙個新的有序序列 將序列的第乙個資料看成是乙個有序的子串行,然後從第二個記錄逐個向該有序的子串行進行有序的插入,直至整個序列有序 可以選擇不同的方法在已經排好序資料表中尋找插入位置。根據查詢方法不同,有多種插入排序方法,下面要介紹的是直接插入排序。設待排序的...