1. 引言html
這一篇咱們來探討選擇問題。 它的提法是:算法
輸入:一個包含n個(互異)數的序列A和一個數i(1≤i≤n)。數組
輸出:元素x(x∈A),且A中有i-1個元素比x小。dom
簡單的說,就是在A中找到第i小的數。spa
2. 指望爲線性時間的選擇算法3d
咱們先給出算法的僞代碼描述:htm
其主要思想與咱們前面介紹的快速排序——算法導論(8)基本同樣,只是在該問題中,咱們每次遞歸時,只用考慮第i小的數可能出現的分組。blog
下面給出Java實現代碼:排序
public static void main(String[] args) { // 1, 2, 3, 4, 5, 7, 9 int[] array = new int[] { 3, 2, 7, 4, 5, 9, 1 }; System.out.println(randomizedSelect(array, 0, array.length - 1, 5)); } public static int randomizedSelect(int[] array, int start, int end, int i) { if (start == end) { return array[start]; } int q = randomPartition(array, start, end); int k = q - start; if (k == i) { return array[q]; } else if (i < k) { return randomizedSelect(array, start, q , i); } else { return randomizedSelect(array, q , end, i-k); } } /** * 重排array,並找出「臨界」位置的索引 * * @param array * 待重排數組 * @param start * 待重排子數組的起始索引 * @param end * 待重排子數組的結束索引 * @return */ public static int partition(int[] array, int start, int end) { int position = start - 1; int base = array[end]; for (int i = start; i < end; i++) { if (array[i] <= base) { position++; int temp = array[position]; array[position] = array[i]; array[i] = temp; } } int temp = array[position + 1]; array[position + 1] = array[end]; array[end] = temp; return position + 1; } public static int randomPartition(int[] array, int start, int end) { int random = (int) (Math.random() * ((end - start) + 1)) + start; int temp = array[random]; array[random] = array[end]; array[end] = temp; return partition(array, start, end); }
咱們能夠證實:上述算法的指望運行時間爲θ(n)。證實略。