對BFPRT演算法理解

2021-09-13 11:18:19 字數 2127 閱讀 8761

對於求乙個陣列中第k小的數, 可以用快速排序的中間過程解決, 例如 找到的基準數的位置》k, 這時候就只需要對於前半部分再進行行 一次這個中間過程.直到找到 第k個數.

然而問題是,快速排序的基準數如果選的不好,範圍就縮小不了1/2甚至還沒有, 時間複雜度可能會到o(n^2).

所以 關於 選擇基準數 可以不隨機選,而是通過如下步驟:

[1] 將陣列每5個分成一組, 可能最後一組不足5個

[2] 進行組內排序, 因為對5個進行排序的時間複雜度可以看成o(1), 所以總消耗o(n).

[3] 將每一組的中位數提取出來形成乙個新的陣列, 這個新的陣列的長度是1  + n/5,  然後對這個新陣列 再進行[1][2][3]步驟, 不過是找這個中位數陣列的1/2位置的元素. 得到它之後, 

[4] 利用得到的中位數陣列的第1/2個數作為基準, 進行快速排序的part過程

對組內排序進行分析, 一開始是o(n) , 遞迴呼叫是  o(n/5) ,  o(n/25)  ... 這個是趨於o(n)的,  然而有空間消耗

/**

* 找出陣列中第k小數字

* @param arr

* @param k 從0開始計數 [0, arr.len-1]

* @return

*/public int bfprt(int arr, int k, int left, int right) else if (right - left <= 0)

final int z = 5;

// 每5個一組, 組內排序

sortforgroup(arr, z, left, right);

// 抽取中位數, 組成乙個新陣列

int newarr = new int[(right - left) / 5 + 1];

getmidnumberformgroup(arr, z, newarr, left, right);

int midvalue = bfprt(newarr, newarr.length / 2 , 0, newarr.length - 1);

int ret = part(arr, 0, arr.length-1, midvalue);

if (ret[0] >= k && ret[1] <= k) else if (k < ret[0]) else

}private void getmidnumberformgroup(int arr, int z, int midarr, int left, int right) else }}

private void sortforgroup(int arr, int z, int left, int right)

arrays.sort(arr, i, j + 1);}}

/*** 這個是快速排序part的過程, base 必須是[left, right]之內的數

* 如果base==null, 隨機去乙個作為基數

* 返回的陣列 ret[0] 是 第乙個等於base的索引位置, ret[1]是最後乙個等於base的索引位置

* @param arr

* @param left

* @param right

* @param base

* @return

*/public int part(int arr, int left, int right, integer base)

threadlocalrandom random = threadlocalrandom.current();

int realbase = (base == null)? arr[left + random.nextint(right - left + 1)] : base;

int lt = left - 1, gt = right;

int i = left;

while (i <= gt) else if (arr[i] > realbase) else

}return new int ;

}public void change(int arr, int i, int j)

int temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

對KMP演算法理解

kmp演算法是一種在乙個字串中匹配另乙個字串的高效演算法。簡單字元的匹配演算法時間複雜度為o m n kmp演算法的時間複雜度為o m n 下面是我在vs上的求next值驗證演算法。include abc.h include using namespace std int main unsigned...

A 演算法理解

廣度優先 bfs 和深度優先 dfs 搜尋 深度優先搜尋,用俗話說就是不見棺材不回頭。演算法會朝乙個方向進發,直到遇到邊界或者障礙物,才回溯。一般在實現的時候,我們採用遞迴的方式來進行,也可以採用模擬壓棧的方式來實現。如下圖,s代表起點,e代表終點。我們如果按照右 下 左 上這樣的擴充套件順序的話,...

我對遺傳演算法理解

1 始祖值 2 隨機交叉 3 優秀標準 4 精英策略 5 收斂 始祖值,a 1 echo print r a echo 雜湊值 any array 2,4,7,8,10,12,51,32,11 echo print r any echo 交叉並啟動精英策略,假設後代的和越大越優秀 foreach a...