微信公衆號:珷玞的日常
上一部分筆記是時間複雜度爲 O(N^2),比較高,適合小規模數據的排序。今天看兩種時間複雜度爲 O(nlogn),歸併排序和快速排序。
歸併排序
歸併排序就是一個典型的分而治之思想的算法,核心思想:將序列分爲前後兩部分,對前後兩部分分別排序,然後合併這兩部分,得到最後結果。
根據歸併的核心思想,我們其實是將排序問題分解爲兩個子問題:前半部分排序,後半部分排序。這兩個子問題又進行分解,最後分解爲單獨元素之後,進行歸併,這也是排序的過程,最後得到結果。
由於歸併使用分而治之的思想,所以我們使用遞歸的方法來實現代碼。具體如下:
# 歸併排序
def mergeSort(l):
if len(l) <= 1:
return l
else:
return mergeSortRecursion(l)
# 遞歸部分,主體部分就是不停的分割合併
def mergeSortRecursion(l):
head = 0
tail = len(l) - 1
if len(l) <= 1:
return l
else:
m = int(len(l)/2)
l1 = mergeSortRecursion(l[head:m])
l2 = mergeSortRecursion(l[m:tail+1])
result = merge(l1,l2)
return result
# 合併函數,進行兩個數組之間的合併
def merge(l,s):
i = 0
j = 0
result = []
while i<len(l) and j<len(s):
# 如果 l 的最後一個元素小於 s 的第一個元素,因爲 l s 都是有序的,所以直接拼接就可以了
if l[-1] <= s[j]:
break
if l[i] <= s[j]:
result.append(l[i])
i += 1
else:
result.append(s[j])
j += 1
result += l[i:]
result += s[j:]
return result
l = [6,5,4,3,2,1]
print([i for i in mergeSort(l)])
分析
-
歸併排序是穩定的排序算法麼?
穩定取決於 merge 函數的比較,我們代碼中是小於等於的時候,result 添加 l[i],所以 l 中的元素始終在 s 的元素前邊,所以是穩定的。
-
歸併排序時間複雜度?
時間複雜度爲 O(nlogn),由於歸併排序的執行效率與要排序的原始數組的有序程度無關,所以時間複雜度很穩定。
快速排序
快速排序也是分而治之思想的一種典型的算法。基本思想:在序列中隨意找一個元素爲基準,然後遍歷其他數據,小於的放在左邊,大於的放在右邊。
代碼實現:
def quick_sort(array, l, r):
if l < r:
q = partition(array, l, r)
quick_sort(array, l, q - 1)
quick_sort(array, q + 1, r)
def partition(array, l, r):
x = array[r]
i = l - 1
for j in range(l, r):
if array[j] <= x:
i += 1
array[i], array[j] = array[j], array[i]
array[i + 1], array[r] = array[r], array[i + 1]
return i + 1
分析
-
快速排序是一種穩定的、原地排序
-
快速排序的時間複雜度
快速排序的時間複雜度爲 O(nlogn)