例如,若ε=9/10,演算法遞迴呼叫所產生的子陣列的長度至少縮短1/10。所以,在最壞情況下,演算法所需的計算時間t(n)滿足遞迴式t(n)≤t(9n/10)+o(n) 。由此可得t(n)=o(n)。
將n個輸入元素劃分成「n/5」個組,每組5個元素,只可能有乙個組不是5個元素。用任意一種排序演算法,將每組中的元素排好序,並取出每組的中位數,共「n/5」個。
遞迴呼叫select來找出這「n/5」個元素的中位數。如果「n/5」是偶數,就找它的2個中位數中較大的乙個。以這個元素作為劃分基準。
設所有元素互不相同。在這種情況下,找出的基準x至少比3(n-5)/10個元素大,因為在每一組中有2個元素小於本組的中位數,而n/5個中位數中又有(n-5)/10個小於基準x。同理,基準x也至少比3(n-5)/10個元素小。而當n≥75時,3(n-5)/10≥n/4所以按此基準劃分所得的2個子陣列的長度都至少縮短1/4。
一般的將每一組的大小定為5,並選取75作為是否作遞迴呼叫的分界點(但不唯一)。這2點保證了t(n)的遞迴式中2個自變數之和n/5+3n/4=19n/20=εn,0
#include
#include
#include
using
namespace std;
#define max 1000
template
<
class
type
>
intpartition
(type a,
int p,
int r,
int k)
swap
(a[i]
, a[j]);
//將左邊不小於基準的與右邊不大於基準的交換
}return i;
//返回基準在陣列的下標值
}template
<
class
type
>
type select
(type a,
int p,
int r,
int k)
for(
int i =
0; i <=
(r - p -4)
/5; i++
)else}}
intmain()
} cout <<
"\n-----------------------------------------\n"
; cout <<
"請輸入要查詢第幾小的數:"
; cin >> k;
int b =
select
(a,0
, max-
1, k)
; cout <<
"第"<< k <<
"小的元素為"
<< b << endl;
sort
(a, a + max -1)
; cout <<
"-----------------------------------------\n"
; cout <<
"排序後的結果為\n"
分治法 線性時間選擇
演算法思想 利用快速排序的方法將a p r 被劃分成兩個子陣列a p i 和a i 1 r 使a p i 中的每個元素都不大於a i 1 r 中每個元素。接著演算法計算子陣列a p i 中元素個數j。如果k j,則第k小的數落在左區間,否則落在右區間,直到k j時,找到第k小的數。對於有重複數字的無...
分治法 線性時間選擇
問題 給定線性序集中n個元素和乙個整數k,1 k n,要求找出這n個元素中第k小的元素,演算法的複雜度為o n 思路分析 首先,假如我們要找最大或者最小的元素,那麼只需遍歷一遍序列即可,複雜度為o n 假如要找第k大的元素,k n logn或者k n nlogn時,利用堆排序,時間複雜度仍然可以達到...
分治法 線性時間選擇(求第k小數)
給定線性序集中n個元素和乙個整數k,1 k n,要求找出這n個元素中第k小的元素,這裡給定的線性集是無序的 線性時間選擇隨機劃分法可以模仿隨機化快速排序演算法設計。基本思想是對輸入陣列進行遞迴劃分,與快速排序不同的是,它只對劃分出的子陣列之一進行遞迴處理。利用隨機函式產生劃分基準,將陣列a p r ...