分治法求線性選擇時間問題

2021-10-01 11:32:45 字數 1696 閱讀 1952

例如,若ε=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 ...