在乙個由n個元素組成的集合中,第i個順序統計量(order statistic
),是該集合中中第i小的元素。例如:最小值是第乙個順序統計量(i = 1),最大值是第n個順序統計量,乙個中位數就是其所在集合的"中點元素。"
當n為奇數時中位數在
,而當n為偶數時,存在兩個中位數,分別是
(下中位數) 和
(上中位數)
在n個元素的集合中,確定乙個最值需要n-1
次比較,其查詢的偽**如下:
minmum(a)
1. min = a[i]
2. for i
3. do if a[i] < min
4. then min = a[i]
5. return min
最大值的查詢方法同理可得,為了確定最值,我們至少需要做n-1
次比較,從執行的次數來看,演算法minmum
是最優的。
面對這個問題我們可以先分別找出最大值和最小值,然後問題就能得到解決,每一次找最值時需要n-1
次比較,那麼總共的比較次數為2n-2
次,但事實上至多需要次就能解決問題。演算法描述:
一開始從資料集合
a
中一次取出兩個值,比較大小後將較小值放入min
將較大值放入max
,然後在剩下的資料集合中取兩個數比較之後將較小值與min
相比,將較大值與max
相比,重複這個過程直至資料集合中的資料為空 (**實現getmin&max)
一般的選擇問題要比找最大值和最小值要難,一般來說需要在乙個集合中查詢第i個值,我們可以對其排序,然後輸出陣列中第i-1的值即可,如果我們使用基於決策樹的排序演算法去處理集合時,那麼最優情況下時間複雜度為o(nlgn)偽**:
randomized-select(a,p,r,i)
1.if p == r
2. then return a[p]
3.q
4.k
5.if i=k
6. then return a[q]
7.elseif i < k
8.then return randomized-select(a,p,q - 1,i)
9.else return randomized-select(a,q+1,r,i-k)
演算法描述:
要明白這個演算法你需要先理解快速排序的隨機劃分過程(詳情可以看我這一篇部落格analysis of quicksort),但是和快速排序不同的是快速排序需要遞迴的處理陣列的兩邊,而randomized-select只需要處理劃分的一邊,那麼這一差異就體現出來了:快速排序的期望執行時間是o(nlgn),而randomized-select期望執行時間為o(n)
我們從陣列a中需要找到第6小的數,在在第一次的劃分中我們得到的數為第五個數(8),所以我們需要在它的右邊部分再劃分,這時由於pivot(8)為第5小的數,我們在右邊部分需要查詢的數應當去掉左邊陣列的個數,即我們需要在右邊部分查詢第1小的數。
randomized-select的最壞情況下的執行時間為theta(n^2),因為在劃分時我們可能極不走運,總是按餘下元素的最大劃分,每次劃分需要theta(n)
基於分治演算法的快速排序
include include include using namespace std const int maxn 10010 int a maxn int n 快排的思路是兩步 split 分治,我們不妨約定,陣列從1開始儲存有效數字 第一步是split,目的是以陣列的第乙個元素為基準,將小於它...
演算法基礎 分治法(基於Python)
有時候,你可能會遇到使用任何已知的演算法都無法解決的問題,這種時候,我們就可以試試分治法的思路。分治法的基本思想很簡單,顧名思義,就是將乙個大問題分解為若干個子問題,然後我們逐一地解決這些子問題,將所有子問題解決完畢,也就將整體的大問題解決完畢了。分治法的精髓 分 將問題分解為規模更小的子問題 治 ...
分治演算法 折半查詢法
二分查詢演算法根據邊界情況不同,一般可分為兩種情況,一中是左閉右開區間,類似於 left,right 一種是左閉右閉區間,在非遞迴二分中,必須遵守一定的區間規則,否則會造成程式錯誤,即區間不能夠重複。思路 假設目標值在閉區間 l,r 中,每次將區間長度縮小一半,當l r時,我們就找到了目標值。題目描...