1. 程式人生 > >演算法--分治演算法

演算法--分治演算法

分治演算法

分而治之,把一個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。如:二分法、快速排序、歸併排序,二叉樹遍歷(先遍歷左子樹再遍歷右子樹)等。

步驟:

  • 分解:將原有問題分解為若干規模較小,相對獨立,與原問題形式相同的子問題;
  • 解決:若子問題容易解決,則直接解;否則繼續分解為更小的子問題,直到容易解決;
  • 合併:將已求解的各個子問題的解逐步合併為原問題的解。

經典遞迴案例:

示例: 歸併排序

詳見:javascript排序演算法

示例:

二分查詢法(二分法)

二分查詢也稱折半查詢,其要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。

  • 假設表中元素是按升序排序,將中間位置的數與要查詢的數做比較;
  • 如果大於該數,則在其左側子表中繼續查詢;否則在右側子表中繼續查詢;
  • 重複上述步驟,知道查詢成功或者不存在。
function binarySearch (find, ary, low, high) {
	let mid = Math.ceil((low + high)/2)
	if (low <= high) {
		if (ary[mid] === find) {
			return
mid } else if (ary[mid] > find) { return binarySearch(find, ary, 0, mid - 1) } else { return binarySearch(find, ary, mid + 1, high) } } return -1 } let ary = [1, 2, 3, 4, 5, 6, 7] binarySearch(3, ary, 0, ary.length - 1)

改造引數

function binarySearch (find, ary) {
	let low = 0
	let high =
ary.length - 1 return (function f (low, high) { let mid = Math.ceil((low + high)/2) if (low <= high) { if (ary[mid] === find) { return mid } else if (ary[mid] > find) { return f(0, mid - 1) } else { return f(mid + 1, high) } } return -1 })(low, high) } let ary = [1, 2, 3, 4, 5, 6, 7] binarySearch(3, ary)