日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

python分治算法_分治法及其python实现例子

發布時間:2025/3/11 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python分治算法_分治法及其python实现例子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在前面的排序算法學習中,歸并排序和快速排序就是用的分治法,分治法作為三大算法之一的,有非常多的應用例子。

分治法概念

將一個復雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題----“分”

將最后子問題可以簡單的直接求解----“治”

將所有子問題的解合并起來就是原問題打得解----“合”

分治法特征

該問題的規模縮小到一定的程度就可以容易地解決

該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質。

利用該問題分解出的子問題的解可以合并為該問題的解;

該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。

第一條特征是絕大多數問題都可以滿足的,因為問題的計算復雜性一般是隨著問題規模的增加而增加;

第二條特征是應用分治法的前提它也是大多數問題可以滿足的,此特征反映了遞歸思想的應用;、

第三條特征是關鍵,能否利用分治法完全取決于問題是否具有第三條特征,如果具備了第一條和第二條特征,而不具備第三條特征,則可以考慮用貪心法或動態規劃法。

第四條特征涉及到分治法的效率,如果各子問題是不獨立的則分治法要做許多不必要的工作,重復地解公共的子問題,此時雖然可用分治法,但一般用動態規劃法較好。

分治法例子:

一、對數組進行快速排序

'''

時間復雜度O(nlogn)

pivot樞紐,low和high為起點終點

'''

#劃分分區(非就地劃分)

def partition(nums=list):

pivot= nums[0] #挑選樞紐

lo = [x for x in nums[1:] if x < pivot] #所有小于pivot的元素

hi = [x for x in nums[1:] if x >= pivot] #所有大于pivot的元素

returnlo,pivot,hi#快速排序

def quick_sort(nums=list):#被分解的Nums小于1則解決了

if len(nums) <= 1:returnnums#分解

lo,pivot,hi =partition(nums)#遞歸(樹),分治,合并

return quick_sort(lo) + [pivot] +quick_sort(hi)

lis= [7, 5, 0, 6, 3, 4, 1, 9, 8, 2]print(quick_sort(lis)) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

二、對數組進行歸并排序

'''名字很多:歸并排序/合并排序/二分排序

時間復雜度 O(logn)

遞歸

兩個步驟:1.拆分 2.合并'''

def merge_sort(nums=list):#取mid以及左右兩個數組

mid = len(nums)//2left_nums,right_nums=nums[:mid],nums[mid:]#遞歸分治

if len(left_nums) > 1:

left_nums=merge_sort(left_nums)if len(right_nums) > 1:

right_nums=merge_sort(right_nums)#合并

res =[]while left_nums and right_nums: #兩個都不為空的時候

if left_nums[-1] >= right_nums[-1]: #尾部較大者

res.append(left_nums.pop())else:

res.append(right_nums.pop())

res.reverse()#倒序

return (left_nums or right_nums) + res #前面加上剩下的非空nums

lis= [7, 5, 0, 6, 3, 4, 1, 9, 8, 2]print(merge_sort(lis)) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

三、給定一個順序表,編寫一個求出其最大值的分治算法

#O(nlogn)

#基本子算法(內置算法)#雖然也可以處理大數組,這里用于解決分治問題規模小于2時候

def get_max(nums=list):returnmax(nums)#分治法

defsolve(nums):

n=len(nums)if n <= 2: #分治問題規模小于2時解決

returnget_max(nums)#分解(子問題規模為 n/2)

left_list, right_list = nums[:n//2], nums[n//2:]#遞歸(樹),分治

left_max, right_max =solve(left_list), solve(right_list)#合并

returnget_max([left_max, right_max])if __name__ == "__main__":#測試數據

alist = [12,2,23,45,67,3,2,4,45,63,24,23]#求最大值

print(solve(alist)) #67

四、給定一個順序表,判斷某個元素是否在其中

#O(nlogn)#子問題算法(子問題規模為1)

defis_in_list(nums,key):if nums[0] ==key:print('Yes! %d in the nums' %key)else:print('Not found')#分治法

defsolve(nums,key):

n=len(nums)#N==1時解決問題

if n == 1:returnis_in_list(nums,key)#分解

left_list,right_list = nums[:n//2],nums[n//2:]#遞歸(樹),分治,合并

res = solve(left_list,key) orsolve(right_list,key)returnresif __name__ == '__main__':#測試

lis = [12,2,23,45,67,3,2,4,45,63,24,23]#查找

print(solve(lis,45)) #YES~

print(solve(lis,5)) #NOT~

五、找出一組序列中的第 k 小的元素,要求線性時間

'''O(nlogn)

用快排的方法,選定pivot然后通過左右兩個分組遞歸得出結果'''

#劃分

def partition(nums=list):

pi=nums[0]

lo= [x for x in nums[1:] if x

hi= [x for x in nums[1:] if x >=pi]returnlo,pi,hi#查找第 k 小的元素

defsolve(nums,key):#分解

lo,pi,hi =partition(nums)

n=len(lo)#解決

if n ==key:returnpi#遞歸分治

elif n

else:returnsolve(lo,key)if __name__ == '__main__':

lis= [3, 4, 1, 6, 3, 7, 9, 13, 93, 0, 100, 1, 2, 2, 3, 3, 2]print(solve(lis,3))#2

print(solve(lis,10))#4

總結

以上是生活随笔為你收集整理的python分治算法_分治法及其python实现例子的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。