寻找最小的k个数

public class FindKMin{
    int[] nums=new int[1000];
    int k=10;
//方法一,先排序,查找前k个
public void sortAndFind(){ int[] arr=Arrays.copyOf(nums, nums.length); Arrays.sort(arr); System.out.println(Arrays.toString(Arrays.copyOfRange(arr, 0, k))); } //方法二,利用选择排序的思想,更新含当前最小k个数的数组 private int findMax(int[] arr){ int max=Integer.MIN_VALUE; int index=-1; for(int i=0;i<arr.length;i++){ if(max<arr[i]){ max=arr[i]; index=i; } } return index; } public void selectAndSwap(){ int[] arr=Arrays.copyOfRange(nums, 0, k); for(int i=k;i<nums.length;i++){ int j=findMax(arr); if(arr[j]>nums[i]){ arr[j]=nums[i]; } } Arrays.sort(arr); System.out.println(Arrays.toString(arr)); }
//方法三,利用大顶堆,来更新含当前最小k个数的数组
public void HeapAndFind(){ int[] arr=new int[k+1]; arr[0]=Integer.MAX_VALUE; for(int i=1;i<k+1;i++){ arr[i]=nums[i-1]; } for(int i=k/2;i>=1;i--){ sink(arr,i,k); } for(int i=k;i<nums.length;i++){ if(arr[1]>nums[i]){ arr[1]=nums[i]; sink(arr,1,k); } } int N=k; while(N>1){ swap(arr,1,N--); sink(arr,1,N); } int[] res=Arrays.copyOfRange(arr, 1,k+1); System.out.println(Arrays.toString(res)); } private void sink(int[] arr, int i, int N) { while(2*i<=N){ int j=2*i; if(j<N&&arr[j]<arr[j+1]) j++; if(arr[i]>=arr[j]) break; swap(arr,i,j); i=j; } } private void swap(int[] arr,int i,int j){ int tmp=arr[i]; arr[i]=arr[j]; arr[j]=tmp; }

//方法四,快速排序
public void quickSortAndFind(){
        int[] arr=Arrays.copyOf(nums, nums.length);
        int K=k;
        sort(arr,0,arr.length-1);
        int[] res=Arrays.copyOfRange(arr, 0, K);
        Arrays.sort(res);
        System.out.println(Arrays.toString(res));
    }
    
    private void sort(int[] arr, int lo, int hi) {
        if(hi<=lo) return;
        int j=partition(arr,lo,hi);
        if(j-lo+1>=k){
            sort(arr,lo,j-1);
        }else{
            k=k-(j-lo+1);
            sort(arr,j+1,hi);
        }
        
    }

    private int partition(int[] arr, int lo, int hi) {
        int i=lo;
        int j=hi+1;
        int v=arr[lo];
        while(true){
            while(arr[++i]<v&&i<hi);
            while(v<arr[--j]&&j>lo);
            if(i>=j) break;
            swap(arr,i,j);
        }
        swap(arr,lo,j);
        return j;
    }

 


    @Test
    public void test(){
        Random random=new Random();
        k=10;
        for(int i=0;i<nums.length;i++){
            nums[i]=random.nextInt(10000);
        }
        sortAndFind();
        selectAndSwap();
        HeapAndFind();
    }
}

 

posted @ 2017-05-15 15:02  wqkant  阅读(127)  评论(0编辑  收藏  举报