随机选择实现

原创
2014/03/06 01:18
阅读数 132

随机选择实现:

可能经常会提到在数组中找第几小或第几大的问题,这里主要以随机选择(找第i小)来实现,其主要思想还是借助快速排序(http://my.oschina.net/indestiny/blog/203927)当中的划分思想来解决,只不过不用对划分后的两个子数组都做处理,只需处理其中一个,思想比较简洁,实现代码如下:

/**
 * 找出数组种从下标p到r之间第i小的数
 * @param arr 目标数组
 * @param p 数组起始索引
 * @param r 数组结束索引
 * @param i 第i小?
 * @return 第i小的数值
 */
private static int randomSelect(int[] arr, int p, int r, int i) {
	if (p == r) return arr[p];
	int q = randomPartition(arr, p, r);
	int k = q - p + 1;
	if (i == k){ 
		return arr[q];
	} else if(i < k){ //第i大在左边数组
		return randomSelect(arr, p, q-1, i);
	} else{ //第i大在右边数组
		return randomSelect(arr, q+1, r, i-k);
	}
}

/**
 * 对数组进行随机划分 
 * @param arr 待划分数组
 * @param p 数组起始索引
 * @param r 数组结束索引
 * @return 最终基准所在的索引值
 */
private static int randomPartition(int[] arr, int p, int r) {
	//[p..r]间产生一个随机索引
	int index = Math.random(p, r); 
	ArrayUtil.swap(arr, index, r);
	return partition(arr, p, r);
}
	
/**
 * 对数组进行划分
 * @param arr 待划分数组
 * @param p 数组起始索引
 * @param r 数值结束索引
 * @return 基准数的索引
 */
private static int partition(int[] arr, int p, int r) {
	int pivot = arr[r];
	int i = p-1;
	for (int j=p; j<=r-1; j++){
		if (arr[j] < pivot){
			i++;
			ArrayUtil.swap(arr, i, j);
		}
	}
	ArrayUtil.swap(arr, i+1, r);
	return i+1;
}
测试用例:
int[] arr = new int[]{12, 32,11, 5,13,4};
int target = 2;
int res = randomSelect(arr, 0, arr.length-1, target);
System.out.println("第"+target +"小的是: " + res);
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
3 收藏
0
分享
返回顶部
顶部