[b]1,增量法(incremental)[/b]
例:插入排序(insertion sort)
ruby版本:
[code]
def insertion_sort(a)
a.each_with_index do |el,i|
j = i - 1
while j >= 0
break if a[j] <= el
a[j + 1] = a[j]
j -= 1
enda[j + 1] = el
endend
[/code]
erlang版本:
[code]
-module(insertion_sort).
-export([sort/1]).
sort(list) ->
sort(list, ).
sort([h | t], acc) ->
sort(t, insert(h, acc));
sort(, acc) ->
acc.
insert(e, acc = [h | _t]) when e < h ->
[e | acc];
insert(e, [h | t]) when e >= h ->
[h | insert(e, t)];
insert(e, ) ->
[e].
[/code]
迴圈了1+2+3+...+(n-1) = n(n+1)/2次,時間為θ(n^2)
[b]2,分治法(divide-and-conquer)[/b]
例:合併排序(merge sort)
ruby版本:
[code]
def merge(l, r)
result =
while l.size > 0 and r.size > 0 do
if l.first < r.first
result << l.shift
else
result << r.shift
endend
if l.size > 0
result += l
endif r.size > 0
result += r
endresult
enddef merge_sort(a)
return a if a.size <= 1
middle = a.size / 2
left = merge_sort(a[0, middle])
right = merge_sort(a[middle, a.size - middle])
merge(left, right)
end[/code]
erlang版本:
[code]
-module(merge_sort).
-export([sort/1]).
sort() -> ;
sort([l]) -> [l];
sort(list) ->
= lists:split(length(list) div 2, list),
merge(sort(left),sort(right)).
merge(l, ) -> l;
merge(, r) -> r;
merge([l|left], [r|_]=right) when l < r ->
[l | merge(left, right)];
merge(left, [r|right]) ->
[r | merge(left, right)].
[/code]
執行了n/2+n/4+n/8+... = n次,時間為θ(n)
回家又看了一下merge sort的時間複雜度的計算方法,發現自己想錯了:
merge時間並不是n/2 n/4 n/8的數列
乙個陣列一直切分切分,最後如果切分到size = 1時,可以認為merge時間為n/2,但向上歸併時size > 1時,這時的merge時間不是簡單的上級的1/2
正確的公式t(n) = 2t(n/2) + cn,其中cn表示合併兩個子陣列的時間,為n的線性函式,分解時間為θ(1),可以忽略
演算法導論對merge sort的時間複雜度的推算方法是擴充套件遞迴樹:
t(n)
||cn + t(n/2) + t(n/2)
||cn + (cn/2 + cn/2) + t(n/4) + t(n/4) + t(n/4) + t(n/4)
||...
cn + (cn/2 + cn/2) + (cn/4 + cn/4 + cn/4 + cn/4) + .... + (c + c + c + ...)
||cn + (cn/2 + cn/2) + (cn/4 + cn/4 + cn/4 + cn/4) + .... + (cn*(1/2)^x + cn*(1/2)^x + cn*(1/2)^x + ...)
cn*(1/2)^x = c
x = lgn
即一共有lgn + 1層,而每層加起來的和又是cn,所以t(n) = cn*(lgn + 1) = θ(nlgn)
演算法導論 CLRS 2 3 7 2 2
2.3 7 其實這道星號題的思路已經在前面幾個習題中給了提示。思路是先用merge sort對陣列公升序排列,然後進行binary search即可,時間複雜度為 t n nlogn logn n logn 演算法分析如下 設二叉搜尋下邊界為lo w 上邊界為hi gh,中間index為mi d 則...
CLRS 17 2核算法
17.2 1 每個 k 次push或pop執行一次copy,那麼使push和pop的 co st為 2 1份用來支付本身的操作,另 1 份用於copy。17.2 2 每次操作的代價都是 3,當 i 不是 2的冪時,支付一美元,信用為 2 美元 否則就支付 i美元,使用信用支付。由於攤還代價是 3 美...
CLRS筆記7 快速排序
quick sort原理很簡單,典型的分治法 1,分陣列a一分為二,比元素x小或等的子陣列和比元素x大的陣列 2,遞迴 子陣列遞迴分 3,合子陣列分好以後按序合併即可 用ruby和erlang實現quick sort實在簡潔 ruby def quick sort a x a.pop quick s...