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
分治法--第K小
最新推荐文章于 2023-09-24 22:35:47 发布