選擇問題——算法導論(10)

1. 引言html

    這一篇咱們來探討選擇問題。 它的提法是:算法

輸入:一個包含n個(互異)數的序列A和一個數i(1≤i≤n)。數組

輸出:元素x(x∈A),且A中有i-1個元素比x小。dom

簡單的說,就是在A中找到第i小的數。spa

2. 指望爲線性時間的選擇算法3d

(1) 算法描述與實現

    咱們先給出算法的僞代碼描述:htm

image

其主要思想與咱們前面介紹的快速排序——算法導論(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);
}

結果:image 遞歸

(2) 算法分析

    咱們能夠證實:上述算法的指望運行時間爲θ(n)。證實略。

相關文章
相關標籤/搜索