演算法 分治法 快速排序,歸併排序

2021-07-17 00:22:16 字數 1598 閱讀 8852

分治法,是演算法思想裡最基礎的思想。這也和人的基本思維有關,當我們需要解決乙個大的問題時,直覺的就會將這個大問題分成多個小問題來解決。

大量的經典演算法,都是基於分治法。比如,快速排序,歸併排序。當然,最讓人想起來的,就是二分查詢了。

分治,分而治之。分的原因是因為問題的規模太大,需要拆開了解決,目的是為了解決問題,分解只是手段。所以分治的步驟其實很明確:

分解:將大問題的分解成小問題,是這個演算法的核心。也是使用分治法的效率保證,如果分解不合理。那麼反而會弄巧成拙。

解決:解決問題,便是分解之後的小問題。他們的解決步驟是相同,至少是相似的。所以,分治法中經常用到遞迴,就是基於這樣的目的。

合併:前面那麼麻煩的兩步,最終的目的仍然是為了解決這個問題。所以需要將分解問題得到的解,合併成最終需要的終極答案,便是這個演算法的結束過程。譬如,你使用遞迴的時候,也需要最後退出的條件。分治法結束條件,就是合併步驟的結束。

雖然很多的運用分治法的演算法,都使用到了遞迴。但是並不是意味著使用了遞迴的演算法,就是使用了分治法。分治法也可使用迭代來實現呀。可以這麼說,一切用尾遞迴方式的演算法,都可以通過乙個棧來迭代實現。遞迴只是演算法的實現手段,基於各語言(大部分)都支援在函式內部呼叫本身特性,可以減少**的重複。

我之所以特此說明,就是我曾經就有這種錯誤的認識。

我前面已經提到的快速排序歸併排序二分查詢。這三種演算法都是經典的演算法,實現方法已有很多人寫了。我就不獻醜了,特別引用了維基百科的快排和歸併的例子,當然依舊是python的實現。

維基百科的快速排序:

def qsort(arr):

if len(arr) <= 1:

return arr

else:

pivot = arr[0]

return qsort([x for x in arr[1:] if x < pivot]) + \

[pivot] + \

qsort([x for x in arr[1:] if x >= pivot])

維基百科的歸併排序:

from collections import deque

def merge_sort(lst):

if len(lst) <= 1:

return lst

def merge(left, right):

merged,left,right = deque(),deque(left),deque(right)

while left and right:

merged.extend(right if right else left)

return list(merged)

middle = int(len(lst) // 2)

left = merge_sort(lst[:middle])

right = merge_sort(lst[middle:])

return merge(left, right)

分治演算法 快速排序,歸併排序

快速排序 分析 資料結構p186.重要 當原始檔有序時複雜度是o n2 此時氣泡排序最好,無序時快速排序是最好的方法。void quicksort int a,int l,int r int i l int j r int x a i a l 即a i 就是第乙個坑 挖坑填數 while j i i...

分治法 快速排序 歸併排序 堆排序

十種常見排序演算法可以分為兩大類 非線性時間比較類排序 通過比較來決定元素間的相對次序,由於其時間複雜度不能突破o nlogn 因此稱為非線性時間比較類排序。線性時間非比較類排序 不通過比較來決定元素間的相對次序,它可以突破基於比較排序的時間下界,以線性時間執行,因此稱為線性時間非比較類排序。0.2...

分治法,歸併排序

1.時間複雜度為o nlog n 非降序 package com.cn.insertion 歸併排序,採用分治法的策略 author administrator public class merge sort mergesort a,0,9 for int i 0 i a.length i 先分在和...