好幾年前就接觸了排序算法,那時候寫都是直接用的brute force方法。那時候心沒有靜下來好好去想,而且只得其形,未得其意,難以理解不同排序算法間的精髓所在。近期在看《圖解算法》這本書,藉助一幅幅圖的表達和演化,恍然頓悟,這算法原來並沒有想象中的那麼難!
插入排序
排序算法的起名,都是和其特性有關,這也是我近來才體會到的,如插入排序(Insert Sort)。從名字上看,和選擇有關,但具體又是如何選的呢,接下來來看看。
假設有這麼個待排序的數組[4,3,1,5,2],使用選擇排序的話,我們要怎麼做呢?
以下是算法的步驟:
- 建立一個空數組1、一個待排序數組2
- 每次從待排序數組中找出最大的一個,插入到數組1中
- 去除待排序數組中當前最大的數
- 重複步驟2,3直到待排序數組爲空
以下是選擇排序的一個樣例:
def find_maxvalue(arr):
find_max = arr[0]
for index in xrange(len(arr)):
if arr[index] > find_max:
find_max = arr[index]
return find_max
def insert_sort(arr):
result = []
while len(arr) > 0:
max_value = find_maxvalue(arr)
result.append(max_value)
arr.remove(max_value)
return result
冒泡排序
生活中,泡泡從水裏冒出來是什麼樣子的呢?是不是越接近水面,泡泡就越大?此排序算法也因此得名,名稱:Bubble Sort。
算法步驟如下:
- 以數組的第一項爲開頭
- 每次比較相鄰兩個元素,並把大的放到後面
- 直到比較至末尾的最後一個元素
- 此時完成一輪比較
- 針對所有的元素重複以上的步驟,除了最後一個(上一輪得到的,以此類推)。
def bubbleSort(arr):
for index in xrange(len(arr)-1):
for j in xrange(index, len(arr)-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
快速排序
這是一種典型的分而治之的算法,通過不斷的將問題分解爲子問題,對要解決的問題進行簡化。記得初中時候就有遇見過這類型的題目(有N個球和一個天平,有一個球比較重,用最少的次數找出來),只不過那時候比較笨,沒有搞清楚到時候爲什麼那麼比較最省力。
算法步驟:
- 選一個key
- 按照這個key值,把比它大的放右邊,比它小的放左邊
- 重複步驟1、2,直到最後分出來的數組只有一個
- 合併結果
def quick_sort(arr):
if len(arr) < 2:
return arr
key = arr[0]
left_side = [i for i in arr[1:] if i < key]
right_side = [i for i in arr[1:] if i >= key]
# print(left_side, right_side)
left_side = quick_sort(left_side)
right_side = quick_sort(right_side)
return left_side + [key] + right_side
總結時刻:
不同的算法,對不同問題的處理情況下有着不同的時間或空間複雜度。因此,選擇時需要結合實際問題,做出適當的調整,這樣可以達到事半功倍的效果。
最佳情況 | 平均情況 | 最壞情況 | |
插入排序 | |||
冒泡排序 | |||
快速排序 |