陣列中查詢第k小元素的複雜度為O(n)的演算法
public class hello{
public static int []aa;
public static void main(String args[])
{
int []b=new int[11];
//int []b={8,4,7,8,6,5,10,8,6,10,8};
int l=0,k=5;
Random rand=new Random();
for(int i=0;i<b.length;++i){
b[i]=rand.nextInt(b.length);
System.out.println(b[i]);
}
aa=b;
//int result1=q_search_rec(l,aa.length-1,k-1); //陣列下標和實際序號差1
//System.out.println("遞迴呼叫的:第"+k+"小的數是");
//System.out.println(aa[result1]);
int result2=q_search_ite_ditto(l,aa.length-1,k-1);
System.out.println("迴圈迭代的:第"+k+"小的數是");
System.out.println(aa[result2]);
}
查詢陣列序列中的第k小元素的程式碼如下,框架類似於quick_sort(),區別是其只對包含第k小元素的那一側進行運算,所以複雜度只有O(n)。
//遞迴快速查詢方法static int q_search_rec(int l,int n,int k)
{
Random rand=new Random();
int t=rand.nextInt(n-l+1)+l;
swap(l,t);
int m,i;
m=l;
for(i=l+1;i<=n;++i)
{
if(aa[i]<aa[l])
{
swap(++m,i);
}
}
swap(l,m);
if(m==k)
return m;
else if(m<k)
return q_search_rec(m+1,n,k);
else
return q_search_rec(l,m-1,k);
}
public static void swap(int a,int b) //交換下標為a,b的元素
{
int c;
c=aa[a];
aa[a]=aa[b];
aa[b]=c;
}
//下面是迭代演算法。注意迭代演算法部分,while迴圈條件是low
int m,i,low =l,high=n;
Random rand =new Random();
while(low<=high){
int t=rand.nextInt(high-low+1)+low;
swap(low,t);
m=low;
for(i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
swap(++m,i);
}
swap(m,low);
if(m==k)
return m;
else if(m<k){
low=m+1;
//System.out.println("low值:"+low);
}
else{
high=m-1;
//System.out.println("high值:"+high);
}
}
return -1;
}
//有大量相同元素,改進演算法效率的方案 即增加q,low~m的小於t,m~q的等於t,q~high的大於t
static int q_search_ite_ditto(int l,int n,int k){
int low,high,m,t,q,xx;
low=l;high=n;
Random rand=new Random();
while(low<=high)
{
t=rand.nextInt(high-low+1)+low;
swap(t,low);
m=low;q=low;
for(int i=low+1;i<=high;++i)
{
if(aa[i]<aa[low])
{
swap(++q,i);
swap(++m,q);
System.out.println("");
}
else if(aa[i]==aa[low])
{
swap(++q,i);
}
}
swap(low,m);
if(k>=m&&k<=q)
{
for(xx=m;xx<=q;xx++)
System.out.println("m~q之間的值:"+aa[xx]);
return m;
}
else if(m>k)
{
high=m-1;
//System.out.println("high值:"+high);
}
else
{
low=q+1;
//System.out.println("low值:"+low);
}
}
return -1;
}
}