分治法--第K小

 
package divideConquer;
/*
 * 		和快速排序一样:
 * 				第K小  [low,high)
 * 			 1.找一个基准,找出其在序列里面的绝对位置 s
 * 			  2.如果K==S,则表示要求的数据就是S
 * 			  3.如果K<S ,那在区间[low,s) 之间找第K个
 * 			  4.如果K>S,在区间[s,high)之间找S-k个
 * 
 * */
public class FirstKSmall {
	public static int partion(int data[],int low,int high)
	{
		int i=low,j=high-1;
		while(i<j)
		{
			while(data[j]>=data[i]&&i<j)
				j--;
			if(i<j) {swap(data,i++,j);}
			
			while(data[i]<=data[j]&&i<j)
				i++;
			if(i<j) {swap(data,i,j--);}
		}
		return i-low;// 返回只是low-high 的相对位置,并不是在数组中的绝对位置
	}
	public static void swap(int data[],int i,int j)
	{
		int tmp = data[i];
		data[i] = data[j];
		data[j] = tmp;
	}
	public static int firstKSmall(int data[],int k,int low,int high)
	{
		if(low+1>=high)
			return data[low];
		int s = partion(data,low,high);// 返回在的S只是在low-high之间的相对位置
		if(k == s)return data[k+low];
		if(k<s) 
			return firstKSmall(data,k,low,s+low);// s+low表示绝对位置
		return firstKSmall(data,k-s-1,s+1+low,high);// s+1+low 表示绝对位置
					//在新区间里找第 k-s-1个数,开始位置后移一个
		
	}
	public static void main(String args[])
	{
		int data[] = {1,1,4,1,1,6};
		System.out.println(firstKSmall(data,5,0,6)); //求第6大的数
	}
}
/*
 * 
 * 		根据些方法还可以延伸出
 * 			1.求最小的K个数
 * 			2.求中位数
 * 			3.求主元素
 * 			
 * */
http://hi.baidu.com/airyoung/blog/item/635bd60802547dca62d986b9.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值