插入排序可以分為直接插入排序與分組插入排序(希爾排序)。直接插入排序的思想類似於整理撲克牌。當我們拿到一副牌的時候,我們希望由小到大進行排序,一般我們會選擇小的牌插入到大的牌後面完成排序。當然這個過程十分感性,況且有我們強大的視覺功能,第一眼往往就能夠識別出最大的牌和最小的牌。
而要讓計算機完成這一操作,這個過程必須要被分為許多邏輯清晰有條有理的步驟。首先,我們將一副長度為n的無序表視為由長度為1的有序表和長度為n的無序表組成。即列表的第乙個數處於有序表,其餘n-1個數均處於無序表中。
接下來,我們要做的是把第二張牌取出,與第一張牌比較決定其插入位置。抽象出來就是,我們將第n張牌取出,與前面排好序的n-1張牌比較,直到某一張牌比第n張牌小為止。
在這個比較過程中,每一次比較都把前n-1張牌的位置往前移一位。即第一次就要把第n張牌的位置給佔掉。因此我們首先就要把第n張牌的值記錄到乙個中間變數裡面,且要把第n張牌的位置也要記錄下來。
def
insertsort
(num)
:for i in
range(1
,len
(num)):
emptycup=num[i]
position=i
while emptycupand position>0:
print
(num[i]
,emptycup)
num[position]
=num[position-1]
position=position-
1 num[position]
=emptycup
return num
num=
[int
(x)for x in
input()
.split()]
print
(insertsort(num)
)
在編寫**中,很容易出現的錯誤是,吧while empty《寫成while num[i]小於,後者實際上是錯誤的,因為emptycup的值是固定的,但是num[i]是有可能被覆蓋的。此外position的用法也值得注意。
從演算法中可以看出,演算法的時間複雜度在o(n^2)數量級。
歸併即先分治再歸併,對於乙個長度為n的無序表,我們永遠將其視為由左右兩部分組成(遞迴的應用)直到列表長度為1為止。此時,按照遞迴的原理,基本結束條件之後開始回遞。
這個時候,乙個長度為n的無序表被分成許多個左右兩部分。且每個左右兩部分的最小部分均只有乙個元素。因此我們只需要比較左右兩部分誰大即可。類似於拉拉鍊,左邊小於右邊則從左邊取出乙個元素放入新的列表,反之則取右邊放入這個列表。值得注意的是,左右兩邊的列表長度不一定相等。因此,當左邊或者右邊取空時,剩下的一邊的元素必然是最大的(大於新列表的所有元素)直接用extend新增入新列表即可。
def
merge
(num):if
len(num)==1
:return num
else
: mid=
len(num)//2
left=merge(num[
:mid]
)# 對左邊進行排序
right=merge(num[mid:])
# 對右邊進行排序
orders=
# 新列表
while left and right:
# 整合左右
if left[0]
>right[0]
:0))
else:0
))orders.extend(right if right else left)
return orders
注意在使用遞迴函式時候,一定要站在全域性來看不能只看細節。一定要弄清楚遞迴函式的作用是什麼,有無返回值,基本結束條件是什麼。要是只看區域性的話很容易混亂。當然能夠很好地利用遞迴實際上很需要經驗和對遞迴很好的理解。
這裡歸併的**,我們參照了陳斌老師的課件比較pythonic。其中while right and left即只要當right和left均不是空列表時。因為空列表等價於false。同理exten(right if right else left) 如果right是true即非空否則就left。
Python筆記 排序演算法(3)
歸併排序和希爾排序 歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。值得注意的是歸併排序是一種穩定的排序方法。將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙...
基於python的幾種排序演算法的實現
usr bin python3 coding utf 8 time 2019 3 28 10 26 author yosef 夜雨聲煩 email wurz529 foxmail.com file sort.py software pycharm defbubble sort arr 氣泡排序 pa...
Python筆記 排序演算法實現(1)
排序是資料結構中常用的方法,現用python實現起泡排序和選擇排序。將被排序的記錄陣列r 1.n 垂直排列,每個記錄r i 看作是重量為r i key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列r 凡掃瞄到違反本原則的輕氣泡,就使其向上 飄浮 如此反覆進行,直到最後任何兩個氣泡都是輕者...