數據結構和算法----排序算法day2

  • 歸併排序
    • 原理:
  • 歸併排序是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法的一個非常典型的應用。 將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。 若將兩個有序表合併成一個有序表,稱爲二路歸併。(以上是官方解釋)
  •            個人理解就是歸併將一組數據用二分法將其分割成無數個小數列,然後再把小數列兩兩排序合併
    • 代碼:
  • #encoding:utf-8
  • #數組合並排序
  • def marge(left,right):
  •     #定義兩個指針,和存儲數組
  •     c = []
  •     a = b = 0
  •     #比較左右子數組指針下的數字大小,並添加到存儲數組
  •     while a < len(left) and b < len(right):
  •         if left[a] > right[b]:
  •             c.append(right[b])
  •             b += 1
  •         else:
  •             c.append(left[a])
  •             a += 1
  •     c += left[a:] + right[b:]
  •     return c
  •     #將左子數組或右子數組剩餘數據存入存儲數組
  •     #返回存儲數組
  • #遞歸分割數組
  • def marge_sort(lis):
  •     list_len = len(lis)
  •     #如果lis長度爲1則返回list
  •     if list_len <= 1:
  •         return lis
  •     #獲取list分割點的下標
  •     middler = list_len // 2
  •     #將分割後的數組繼續分割直到長度爲一爲止
  •     left = marge_sort(lis[:middler])
  •     right = marge_sort(lis[middler:])
  •     #將分割後的數組排序合併
  •         return marge(left,right)
    • 分析:
  • 空間複雜度:因爲每次合併都需要申請一個存儲空間,合併之後釋放掉所以,所以臨時內存空間不會超過數列的元素個數也就是n,所以空間複雜度爲O(n)
  • 時間複雜度:遞歸的時間複雜度用公式來看
  •             T(n) = 2 * T(n/2) + n  
  •             T(n):時間複雜度
  •             2*T(n/2):二分的時間複雜度
  •             n:合併的時間複雜度
  •             最後算得T(n) = O(nlogn)
  •                      穩定性:如果左右數組值相等,那麼先存左數組數據,就能保證其穩定性。所以歸併排序是穩定得排序算法
  • 快速排序
    • 原理:
  • 先從數列中取出一個數作爲基準數。
  • 分區過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
  • 再對左右區間重複第二步,直到各區間只有一個數。
    • 代碼:
  • def quick_sort(array, l, r):
    
        #如果左右邊界相等則返回
    
        if r > l:
    
            #定義分區點位置得指針
    
            i = l
    
            #定義分區點
    
            key = array[r]
    
            #遍歷數組將小於分區點得數據都放入分區點左面
    
            for j in range(l,r):
    
                if key > array[j]:
    
                    array[i],array[j] = array[j],array[i]
    
                    i += 1
    
            #將分區點放入指針指定得位置
    
            array[r],array[i] = array[i],array[r]
    
            #排序結束將分區點左右子數組進行遞歸排序
    
            quick_sort(array,l,i-1)
    
            quick_sort(array,i+1,r)
  •  
  • python實現一行代碼的快排:
  • quick_sort = lambda array: array if len(array) <= 1 else  quick_sort([item for item in array[1:] if item <= array[0]]) + [array[0]] +  quick_sort([item for item in array[1:] if item > array[0]])
  • 拆分理解一下
  • # 這個不難理解如果數組長度小於等於一表達式結果就爲array本身
    
    quick_sort = lambda array: array if len(array) <= 1 else \
    
    # 取出array中小於分區點的所有元素,放在分區點左面
    
        quick_sort([item for item in array[1:] if item <= array[0]]) + \
    
    #分區點
    
        [array[0]] + \
    
    #取出array中大於分區點的所有元素,放到分區點右面
    
        quick_sort([item for item in array[1:] if item > array[0]])
  • 仔細看不難,但是要是自己寫需要費點心神
    • 分析:
  • 空間複雜度:原地排序O(1)
  • 時間複雜度:同樣寫出公式分析
  •          T(n) = 2 * T(n/2) + n與歸併排序相同,所以時間複雜度同爲O(nlogn)
  • 穩定性:不穩定
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章