高階排序主要會展示歸併排序演算法和快速排序演算法。歸併排序演算法由於不是原地排序演算法所以它的空間複雜度不是o(1),它的時間複雜度是o(nlogn)。整個演算法如果採用遞迴方式去寫的話是很簡單的,具體可參看**部分。
快速排序的思路和歸併排序是一樣的,就是把陣列分成兩部分分別使其有序最後在組合起來就整體有序了。不同的是快速排序並不是平均拆分陣列,而是選擇乙個中心點,排序時讓中心點左邊的數都比中心點小,中心點右邊數都比中心點大,這個排序演算法的時間複雜度是o(n), 但是由於陣列拆分是基於中心點的,所以它的拆分的時間複雜度和它選擇的這個點有很大關係,具體情況可以看**分析。
/**
** 歸併排序
* 用到的分治的思想
* 假如乙個陣列 前半部分和後半部分都是有序的, 那麼它的排序時間複雜度是o(n)
* 那麼有:
* a(m, n) = a(m, k) + a(k + 1, n)
* 當 m = k 時 說明陣列只有乙個數字那麼它自然有序了
* 同理n = k + 1 也是
* 所以我們只需要把陣列 拆成 長度為乙個 陣列集,排序後再組合起來那麼整個陣列就有序了
* 那麼剩下我們就要看看把陣列 拆成 長度為一的陣列集,需要的時間複雜度是多少
* * 假如陣列長度 為 n, 我們每次 拆一半,最終得到 陣列長度為1
* 數學等式可以寫為:
* n*(1/2)^x = 1 => 2^x = n => x = log(2)n (注意n是log的真數) => o(logn)
* * 所以整個演算法的時間複雜度為: o(nlogn)
* *
* @param s
* */
public
function
mergesort
(s:array)
:void
private
function
merge
(s:array, m:int, n:int)
:array
var k:int = math.
floor
((m + n)/2
);var t1:array =
merge
(s, m, k)
;var t2:array =
merge
(s, k +
1, n)
;//這裡合併成乙個
var q:int =
0, p:int =0;
for(
var i:int =
0; p <= k - m && q <= n - k -
1; i++
)else
}//把剩下的補齊
while
(p <= k-m)
while
(q <= n - k -1)
return temp;
}
/**
*快速排序
* 用到的分治的思想
* 假如乙個陣列 前半部分和後半部分都是有序的, 那麼它的排序時間複雜度是o(n)
* 那麼有:
* a(m, n) = a(m, k) + a(k + 1, n)
* 當 m = k 時 說明陣列只有乙個數字那麼它自然有序了
* 同理n = k + 1 也是
* 所以我們只需要把陣列 拆成 長度為乙個 陣列集,排序後再組合起來那麼整個陣列就有序了
* 那麼剩下我們就要看看把陣列 拆成 長度為一的陣列集,需要的時間複雜度是多少
* * 注意拆分的策略和歸併排序不一樣, 這裡的拆分和選擇的對比點有很大關係
* 我們每次選擇最後乙個點
* 假如選擇點能平分陣列 那麼時間複雜度就和歸併排序一樣 o(logn)
* * 假如陣列是有序的 [1,2,3,4,5,6,7,8],
* 那麼我們拆分的情況就是
* [1,2,3,4,5,6,7,8] => [1,2,3,4,5,6,7] | 8 => [1,2,3,4,5,6] | 7,8 => ... => | 1,2,3,4,5,6,7,8
* 可以看出總共要進行n次拆分 所以時間複雜度是o(n)
* * 而如果輸入是完全無序的[8,7,6,5,4,3,2,1]
* 那麼我們的拆分情況是
* [1,2,3,4,5,6,7,8] => 1 | [2,3,4,5,6,7,8] => 1,2 | [3,4,5,6,7,8] => ... => 1,2,3,4,5,6,7,8 |
* 也是o(n)
* * 所以可以看出,中心點的選擇是很重要的,我們需要盡量選擇可以平分陣列的點
* 它最好的情況是 o(nlogn), 最差的情況是 o(n²)
* * @param s
* */
public
function
quicksort
(s:array)
:void
private
function
quick
(s:array, m:int, n:int)
:void
//每次都選最後乙個作為中心點
var j:int = m;
//已排序區域起始序號
var value:int;
//排序
for(
var i:int = m; i < n; i++
)else
//否則假如元素比它大,則不做任何交換
}//排序完成之後把最後乙個值,與已排序列表的最後一位交換
value = s[j]
; s[j]
= s[n]
; s[n]
= value;
trace
(s);
quick
(s, m, j -1)
;quick
(s, j +
1, n)
;}
WPF天天見系列
為了能更好的實現產品與vista作業系統的移植 相容 擴充套件等等。最近 或許一直 一段時間開始學習wpf的一些相關知識。根據目前的安排,至少還有1個月的時間。正好,可以每天記錄一些問題或者所學的知識。也希望自己能堅持寫下去。我們都相信時間的力量!大寶能天天見,wpf也可以天天寫!持續更新中.閒話w...
WPF天天見系列
為了能更好的實現產品與vista作業系統的移植 相容 擴充套件等等。最近 或許一直 一段時間開始學習wpf的一些相關知識。根據目前的安排,至少還有1個月的時間。正好,可以每天記錄一些問題或者所學的知識。也希望自己能堅持寫下去。我們都相信時間的力量!大寶能天天見,wpf也可以天天寫!持續更新中.閒話w...
WPF天天見系列 閒話WPF之一(WPF的結構)
wpf可以認為是ms利用原有.net框架的一些特色,加上dirextx的產物。從下圖的wpf元件中,我們可以看出最底層仍然是一些核心api。以下兩張都來自網際網路。其中紅色顯示的元件是wpf的核心。milcore是乙個和directx互動的非託管元件,非託管 能帶給我們更高效的處理,能更好的和dir...