分治策略(入門)

2022-04-08 04:57:56 字數 3158 閱讀 4139

小編今天學習了一下 分治策略(參考 演算法導論),並用python**實現了一下 例項中的 方法。大家一起相互學習啦。

首先是 插入排序的方法:

時間複雜度為 (n^2)。

**實現如下:

#

插入排序法

a = [2,1,6,5,4,8,9]

for i in

range(int(len(a))):

for j in range(int(len(a))-1):

if a[j] > a[j+1]:

b =a[j]

a[j] = a[j+1]

a[j+1] =b

print("

增序列表

" + str(a))

然後就是:

歸併排序法,時間複雜度為 nlog(n):

#

歸併排序法

a = [2,1,6,5,4,8,9]

defmerge(a, p, q, r):

n1 = q - p + 1n2 = r -q

l1 =

l2 =

for i in

range(n1):

l1.insert(i, a[p+i])

for j in

range(n2):

l2.insert(j, a[j+q+1])

i =0

j =0

for k in range(p, r+1):

if l1[i] <=l2[j]:

a[k] =l1[i]

i += 1

else

: a[k] =l2[j]

j += 1

defmerge_sort(a, p, r):

if p

q = int((p + r)/2)

#print(q)

merge_sort(a, p, q)

merge_sort(a, q+1, r)

merge(a, p, q, r)

merge_sort(a, 0, 6)

print(a)

歸併排序就是用了 分治策略。

相關的問題 有——最大子陣列問題。

諸如下述的列表:

代表著16天以來的**增長情況,要求選出一天**,一天賣出,最後獲得盈利最大。

a = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]

有兩種情況,一種是暴力求解的方法,一種是利用分治策略。

首先,實現 暴力求解,就是列舉出所有的情況,選取利益最大的情況。

依次遍歷。

a = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]

max_sum =0

for i in range(16):

sum =0

for j in range(i+1, 16):

sum = sum +a[j]

if sum>max_sum:

max_sum =sum

left = i+1right =j

print(left, right, max_sum)

另一種方法就是利用分治策略,任何連續陣列必然是下列三中情況下的一種:

1  完全位於陣列的low---mid 之中

2  完全位於陣列的mid--high之中

3  陣列跨越了 mid

def find_max_crossing(a, low, mid, high):

left_sum = -1000sum =0

for i in range(mid, low-1, -1):

sum = sum +a[i]

if(sum>left_sum):

left_sum =sum

max_left =i

right_sum = -1000sum =0

for j in range(mid+1, high+1):

sum = sum +a[j]

if(sum>right_sum):

right_sum =sum

max_right =j

return (max_left, max_right, right_sum+left_sum)

deffind_max_subarray(a, low, high):

if(low==high):

return

(low, high, a[low])

else

: mid = int((low+high)/2)

(left_low, left_high, left_sum) =find_max_subarray(a, low, mid)

(right_low, right_high, right_sum) = find_max_subarray(a, mid+1, high)

(cross_low, cross_high, cross_sum) =find_max_crossing(a, low, mid, high)

if((left_sum>=right_sum) and (left_sum>=cross_sum)):

return

(left_low, left_high, left_sum)

elif((right_sum>=left_sum)and(right_sum>=cross_sum)):

return

(right_low, right_high, right_sum)

else

:

return

(cross_low, cross_high, cross_sum)

(a,b,c) = find_max_subarray(a, 0, 15)

print(str(a) + '

\n' + str(b) + '

\n' + str(c))

下面  附上 兩種方法在 陣列有16個值的時間對比情況:

分治入門 樹分治

分治思想 劃分子問題,解決子問題,合併子問題 題目 poj1741 題意 給定一棵含有n個節點的無向帶權樹,滿足距離 k的兩點共有多少對?n 1e4 題解 1 首先找到樹a的重心,重心指的是乙個節點,將該節點刪去之後剩下的最大子樹的節點數最小 將其作為樹a的根。在數列的分治之中我們是直接去區間的中間...

分治入門 平面分治

分治思想 劃分子問題,解決子問題,合併子問題 題目 uva 10245 題意 在乙個二維平面內給定n個點,求最近的兩個點的距離。n 10000 題解 直接暴力列舉所有點是肯定行不通的。那麼基於分治的思想 按照橫座標排序後,分成兩個部分,那麼最近距離的點對就是以下的情況 1 兩個點均屬於乙個區域 2 ...

分治策略 快速排序

快速排序演算法是基於分治策略的另乙個排序演算法。其基本思想是 對輸入的子陣列a p r 按以下三個步驟進行排序。1 分解 divide 以a p 為基準元素將a p r 劃分成3段a p q 1 a q 和a q 1 r 使得a p q 1 中任何乙個元素小於等於a q 而a q 1 r 中任何乙個...