关闭

求序列第K大数的部分快速排序法

441人阅读 评论(0) 收藏 举报
分类:

用的是经典快速排序方法,每次快排都可以确定一个键的位置,得到关键字的下标,则可判断需要找的第K小的数在其左边还是右边,然后继续快排,直至找到恰好等于关键字为止。。

 

快速排序的基本思想是:每次从无序的序列中找出一个数作为中间点(可以把第一个数作为中间点),然后把小于中间点的数放在中间点的左边,把大于中间点的数放在中间点的右边;对以上过程重复log(n)次得到有序的序列。

平均情况下它的时间复杂度为O(nlog(n))

 

public class Kth {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int m=scan.nextInt();                  //序列个数
        int k=scan.nextInt();                   //第k小的数
        int[]a=new int[m];
        for(int i=0;i<m;i++){
            a[i]=scan.nextInt();
        }
        System.out.println(QSort(a,0,a.length-1,k));           
    }
   
    public static int QSort(int[]a,int low,int high,int key){
        if(low<high){
            int k=QR(a,low,high);
            int h=k-low;       //比a[k]小的数有h个
            if(h+1==key) return a[k];     //a[k]是第h+1小的数
            if(h<key)
            return QSort(a,k+1,high,key-h-1);       //a[k]右边的第key-h-1个数
            else
            return QSort(a,low,k-1,key);            //a[k]左边第key个数
        }
        return a[low];                              //若low==high 则证明缩减到一个数了
    }
    public static int QR(int[]a,int low,int high){          //一次
        int key=a[low];
        while(low<high){
            while(low<high&&a[high]>=key) high--;
            a[low]=a[high];
            while(low<high&&a[low]<=key) low++;
            a[high]=a[low];
        }
        a[low]=key;
        return low;
    }
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场