演算法設計與分析 分治法(js實現)

2021-10-07 18:44:03 字數 4592 閱讀 9310

特徵

能否利用分治法完全取決於問題是否具有這條特徵,如果具備了前兩條特徵,而不具備第三條特徵,則可以考慮貪心演算法或動態規劃。

偽**
divide-and-

conquer

(p)if

(|p|

<= n0)

adhoc

(p);

//解決小規模的問題

divide p into smaller subinstances pl,p...

.pk;

//分解問題

for(i=

1,i<=k,i++

) yi=divide-and-

conquer

(pi)

;//遞迴的解各子問題

returnmrrge...

.yk)

;//將各子問題的解合併為原問題的解

人們從大量實踐中發現,在用分治法設計演算法時,最好使子問題的規模大致相同。即將乙個問題分成大小相等的k個子問題的處理方法是行之有效的。這種使子問題規模大致相等的做法是出自一種平衡(balancing)子問題的思想,它幾乎總是比子問題規模不等的做法要好。

例子

求指定整型陣列的最大值和最小值。

傳統做法就是遍歷一遍下來求出最大值和最小值,時間複雜度是o(n)。

function

divide_conquer

(arr,

from

,to)

}else

if(to -

from==0

)}else;if

(result1[

"max"

]> result2[

"max"])

else

if(result1[

"min"

]> result2[

"min"])

else

return result;}}

var arr =[34

,5,6

,7111,7

,8,889,9

];console.

log(

divide_conquer

(arr,

0,arr.length-1)

);

二分搜尋
給你一-個裝有16個硬幣的袋子。16個硬幣中有一 個是偽造的,並且那個偽造的硬幣比真的硬幣要輕一些。你的任務是找出這個偽造的硬幣。為了幫助你

完成這一任務,將提供臺可用來比較兩組硬幣重量的儀器,利用這台儀器,可以知道兩組硬幣的重量是否相同。

演算法描述

將16個硬幣分成a、b兩半;

將a放儀器的一邊, b放另-邊,如果a袋輕,則表明偽幣在a ,解子問題a即可,否則,解 子問題b。 例項

給定已按公升序排好序的n個元素a|0:n-1|,現要在這n個元素中找出特定元素x。

function

binarysearch

(arr, target));

// console.log(arr.sort((a, b) => ))

let left =0;

let right = arr.length -1;

while

(left <= right)

else

if(arr[mid]

< target)

else

}return

"該數不存在"

}binarysearch([

3,2,

1,3,

4,6,

7],1

);console.

log(

binarysearch([

3,2,

1,3,

4,6,

7],1

))

快速排序

思路偽**

template<

class

type

>

void

quicksort

(type a]

, int p, int r)

例項
// 快速排序

/* 思想:二分的操作,遞迴的思想,分成左右兩個陣列,比當前小的放左邊,大的放右邊,重複以上操作,當遞迴到剩下的長度為<=1

時間複雜度 o(nlog n)

*/function

quick

(arr)

// 找到陣列的中間向,在原有的陣列中把他移除

let mid = math.

floor

(arr.length/2)

;let midvalue = arr.

splice

(mid,1)

[0];

// 準備左右兩個陣列,迴圈剩下陣列中的每一項,比當前小的放左邊,大的放右邊

let arrright =

, arrleft =

;for

(let i =

0;i)// 遞迴方式讓左右兩邊都排好序

return

quick

(arrleft)

.concat

(midvalue,

quick

(arrright));

}quick([

23,54,

67,57,

87,798,56,

1,2,

4])

快排的進一步思考

偽**

template<

class

type

>

int randomizedpartition

(type a[

], int p, int r)

歸併排序

演算法描述

若n為1 ,演算法終止;否則,將這一元素集合分割成兩個或更多個子集合,對每- -個子集合分別排序然後將排好序的子集合歸併為乙個集合。

例項
function

mergesort

(arr)

const mid = math.

floor

(length /2)

;//分成左右兩個部分

const left = arr.

slice(0

, mid)

;const right = arr.

slice

(mid, length)

;return

merge

(mergesort

(left)

,mergesort

(right));

//要將原始陣列分割直至只有乙個元素時,才開始歸併

}function

merge

(left, right)

else

}//不可能同時存在left和right都有剩餘項的情況, 要麼left要麼right有剩餘項, 把剩餘項加進來即可

while

(il < left.length)

while

(ir < right.length)

return result;

}console.

log(

mergesort([

2,9,

1,8,

3,])

)

覆蓋殘缺棋盤

偽**

void

chessboard

(int tr, int tc, int dr, int dc, int size)

if(size ==1)

return

;intt= tile++

,//l型骨牌號

s= size/2;

//分割棋盤

//覆蓋左上角子棋盤

if(dr//特殊方格在此棋盤中

chessboard

(tr, tc, dr, dc, s)

;else

//覆蓋右上角子棋盤

if(dr=tc+ s)

/1特殊方格在此棋盤中

chessboard

(tr, tc+s, dr, dc, s)

;else

//覆蓋左下角子棋盤

if(dr>=tr+ s&&dc//特殊方格在此棋盤中

chessboard

(tr+s, tc, dr, dc, s)

;else

//覆蓋右下角子棋盤

if(dr>=tr+ s&& dc>=tc+ s)

//特殊方格在此棋盤中

chessboard

(tr+s, tc+s, dr, dc, s)

;else

}

複雜度分析

複雜度分析

0(1)k=0

t(k)= 4t(k-l)+o(1) k>0

​ t(n)=o(4k) 漸進意義下的最優演算法

演算法設計與分析基礎 分治法

1.將乙個問題劃分為同一型別的若干子問題,子問題最好規模相同 2.對子問題求解 一般使用遞迴方法 3.有必要的話,合併子問題的解,得到原始問題的答案 下圖描述的是將乙個問題劃分為兩個較小子問題的例子,也是最常見的情況 1.主要思想 對於乙個需要排序的陣列a 0 n 1 將其一分為二 a 0 n 2 ...

演算法設計與分析複習 分治法演算法描述

分治 劃分 解子問題 組合 每個遞迴演算法均可以轉換為迭代演算法 include include 尋找最大最小元素,最大比較次數 3 n 2 2 minmax low,high if high low 1 if arr low arr high return arr low arr high els...

演算法設計與分析之分治法 棋盤覆蓋

棋盤覆蓋問題要求在2 k 2 k 個方格組成的棋盤中,你給定任意乙個特殊點,用一種方案實現對除該特殊點的棋盤實現全覆蓋。建立模型如圖 解決方案就是利用分治法,將方形棋盤分成4部分,如果該特殊點在某一部分,我們就去遞迴他,如果不在某一部分,我們假設乙個點為特殊點,同樣遞迴下去,知道全覆蓋。左上角的子棋...