基於分治的查詢演算法

2022-09-11 20:18:15 字數 2092 閱讀 5926

在乙個由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時,我們就找到了目標值。題目描...