CLRS筆記2 演算法入門

2021-08-29 17:20:31 字數 2551 閱讀 1844

[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...