(快排实例)查询一个数组中第n大的元素

来源:互联网 发布:js遍历二维数组 编辑:程序博客网 时间:2024/05/22 15:59
package cyd;/** * 查询一个数组中第n大的元素  * 借用了快速排序的思想, * 我先选定一个标定值 然后将数组等分小于这个数的放在左边 大于的放在右边  这时标定值的位置是正确的 我们将它返回去 跟我们的n比较 * 如果返回值大于n我们 就只需要查左边的数据  如果小于n 就只需要查右边的数据   然后递归求解 即可 *  * 只需要O(2n) 的时间复杂度 就能查到想要的结果 *  复杂度 = n + n/2 + n/4 +n/8 ...   = O(2n) * @author 1 * */public class SelectNum {public static void main(String[] args) {int[] arr = randomArr(1000, 0, 1000);int quickSortgetNum = quickSortgetNum(arr,20);System.out.println(quickSortgetNum);}//快速排序public static int quickSortgetNum(int[] arr,int n){return __quickSort(arr , 0, arr.length - 1,n -1 );}//递归实现快速排序  //每次找到当前的中间值,然后等分左右,再继续从左右依次这样做 就实现了快速排序private static int __quickSort(int[] arr, int l, int r, int n) {int p = __partition(arr, l, r);System.out.println(p+"-----"+arr[p]);//递归求解if(p > n){return __quickSort(arr, l, p - 1, n);}else if(p < n){return __quickSort(arr, p + 1, r, n);}else{return arr[p];}}//快速排序核心private static int __partition(int[] arr, int l, int r) {//这是标准位置的值,最后排序完成左边的比这小右边的比这大//初始版本  取第一个元素 ,但是有一个弊端 如果 数组本身近乎有序,那么大于当前值的就会非常多,导致右侧元素多,就会导致快速排序退化成O(n^2)级别的排序//int p = arr[l];//改进  从 l 到   r 中随机取 一个数  与 起始位置交换作为起始位置,这时 就不会出现这种情况了swap(arr, l , (int) (Math.round((Math.random()*(r - l) + l))));int p = arr[l];int j = l;for(int i = l + 1; i <= r; i++){if(arr[i] < p){swap(arr, i , j + 1);j++;}}swap(arr, j , l);return j;}//输出    public static void printArr(int[] arr){        for(int i = 0; i < arr.length; i++){            if(i != arr.length - 1){                System.err.print(arr[i]+",");            }else{                System.err.println(arr[i]);            }        }    }    /**     * 生成随机数     * @param size     * @param rangeL     * @param rangeR     * @return     */    public static int[] randomArr(int size, int rangeL, int rangeR){        if(rangeL >= rangeR){            return null;        }        int arr[] = new int[size];        for(int i = 0; i < size; i++){            arr[i] = (int) (Math.round((Math.random()*(rangeR - rangeL ) + rangeL)));            for(int j = 0; j <=i; j++ ){                if(i != j){                    if(arr[i] == arr[j] ){                        i--;                        break;                    }                }            }        }        return arr;    }    public static boolean isSortArr(int[] arr){        for(int i =0 ; i < arr.length - 1; i++){            if(arr[i] > arr[i + 1]){                return false;            }        }        return true;    }    //交换    public static void swap(int arr[], int leftNum, int rightNum){        int temp = arr[leftNum];        arr[leftNum] = arr[rightNum];        arr[rightNum] = temp;    }}