算法筆記 7 歸併排序和快速排序(上)

微信公衆號:珷玞的日常

上一部分筆記是時間複雜度爲 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)])

分析

  1. 歸併排序是穩定的排序算法麼?

穩定取決於 merge 函數的比較,我們代碼中是小於等於的時候,result 添加 l[i],所以 l 中的元素始終在 s 的元素前邊,所以是穩定的。

  1. 歸併排序時間複雜度?

時間複雜度爲 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

分析

  1. 快速排序是一種穩定的、原地排序

  2. 快速排序的時間複雜度

快速排序的時間複雜度爲 O(nlogn)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章