在N个元素中选取前M个元素

import org.junit.Test;

public class solution {
    
    @Test
    public void testFunc(){
//        int[] arr = {5,4,3,2,1};
        int[] arr = {1,2,3,4,5,6};
        maxArr(arr,3);
        for(int i=0;i<5;i++){
            System.out.print(arr[i]+"  ");
        }
        
    }
    /*
     * 问题:在N个元素中选取前M个元素
     * 思路:1 建立长度为M的数组,作为最小堆   或则arr[0,m-1]构建小顶堆
     *     3 先往最小堆中存入一部分元素
     *     2 遍历n个元素,如果元素的值大于最小堆的顶点,则交换两个数的值,并对r[0]执行shiftDown
     *     
      */
    public boolean maxArr(int[] arr, int m){
        if (arr.length<m || arr.length==0 || m==0) {
            return false;
        }
        for(int i=(m-2)/2;i>=0;i--){
            shiftDown(i, m-1, arr);
        }
        int maxIndexArr = arr.length-1;
        for(int i = m;i<=maxIndexArr;i++){
            if (arr[0]<arr[i]) {
                swap(arr, 0, i);
                shiftDown(0, m-1, arr);
            }
        }
        
        return true;
    }
    
    private void shiftDown(int k, int maxIndex ,int[] arr){
        while (2*k+1<=maxIndex) {
                int index = 2*k+1;
                if (index+1<=maxIndex && arr[index+1]<arr[index]) {
                    index = index+1;
                }
                if (arr[k]<arr[index]) {
                    break;
                }
                swap(arr, k, index);
                k = index;
        }
        
    }
    private void swap(int[] arr, int k, int index) {
        // TODO Auto-generated method stub
        int temp = arr[index];
        arr[index] = arr[k];
        arr[k] = temp;
    }
    
    
}

猜你喜欢

转载自blog.csdn.net/wwzheng16/article/details/80977009