小編今天學習了一下 分治策略(參考 演算法導論),並用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):下面 附上 兩種方法在 陣列有16個值的時間對比情況: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))
分治入門 樹分治
分治思想 劃分子問題,解決子問題,合併子問題 題目 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 中任何乙個...