zoukankan      html  css  js  c++  java
  • 基于快速排序思想partition查找第K大的数或者第K小的数。

    快速排序

    下面是之前实现过的快速排序的代码。

    function quickSort(a,left,right){
        if(left==right)return;
        let key=partition(a,left,right);//选出key下标
        if(left<key){
            quickSort(a,left,key-1);//对key的左半部分排序
        }
        if(key<right){
            quickSort(a,key+1,right)//对key的右半部份排序
        }
    }
    function partition(a,left,right){
        let key=a[left];//一开始让key为第一个数
        while(left<right){//扫描一遍
            while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
                right--;
            }
            [a[left],a[right]]=[a[right],a[left]];//交换
            while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
                left++;
            }
            [a[left],a[right]]=[a[right],a[left]];//交换
        }
        return left;//把key现在所在的下标返回
    }

    明显我们可以看出快排的思想是每次找到一个基准数,将数组排列成基准数左边的每个数都比基准数大,右边的每个数都比基准数小的序列。 通过这个思想,我们可以稍微修改QuickSort函数,使它变成findKmax函数,使之拥有快速查找前k个最大的数。

    基于快速排序思想查找第K大的数

    function findKmax(a,k){
        let left=0,right=a.length-1;
        let key=partition(a,left,right);
        let len=a.length-key;
        while(len!=k){
            if(len>k){
                key=partition(a,key+1,right);
            }else{
                key=partition(a,left,key-1);
            }
            len=a.length-key;
        }
        return a[key];
    }
    function partition(a,left,right){
        let key=a[left];//一开始让key为第一个数
        while(left<right){//扫描一遍
            while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
                right--;
            }
            [a[left],a[right]]=[a[right],a[left]];//交换
            while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
                left++;
            }
            [a[left],a[right]]=[a[right],a[left]];//交换
        }
        return left;//把key现在所在的下标返回
    }

    重点是要注意判定边界条件,left,right,k三个都在变,因此需要检验

    同理,还可以求第K小的数

    function findKmin(a,k){//查找第K小的数
        let left=0,right=a.length-1;
        let key=partition(a,left,right);
        while(key!=k-1){
            if(key>k-1){
                key=partition(a,left,key-1);
            }else{
                key=partition(a,key+1,right);
            }
        }
        return a[key];
    }
    function partition(a,left,right){
        let key=a[left];//一开始让key为第一个数
        while(left<right){//扫描一遍
            while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
                right--;
            }
            [a[left],a[right]]=[a[right],a[left]];//交换
            while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
                left++;
            }
            [a[left],a[right]]=[a[right],a[left]];//交换
        }
        return left;//把key现在所在的下标返回
    }
  • 相关阅读:
    mac 提示app已经损坏打开的方法
    查看mac ip地址
    前端页面输入框合法性校验
    mybatis报错:Cause: java.sql.SQLSyntaxErrorException: Unknown column 'end_date' in 'field list'
    mybatis项目报错:Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
    项目中遇到的错误:Caused by: java.net.BindException: Address already in use: bind
    hashMap&hashtable&ConcurrentMap的区别
    3.java面试题(三)
    Mybatis项目启动时报错:The server time zone value '�й���׼ʱ��' is unrecognize
    1.java面试题(一)
  • 原文地址:https://www.cnblogs.com/wuguanglin/p/searchKMax.html
Copyright © 2011-2022 走看看