找第k小元素

1.分治法

算法思想
1.分解:
使用Random Partition对数组array进行划分
2.解决
对主元素i进行分析,若i等于k,则返回该位置;若ik,说明第k小元素落在数组的array[0 …i-1]之中,递归分析数组array[0 …i-1]的第k小元素
3.合并
由题意知找到第k小元素即可,无需合并

代码实现

//分治法,基于快排的随机化
 
public class search_Kth_Smallest {

    public static void main(String[] agrs) {
        int[] array = new int[]{1, 1, 2, 4, 9, 3, 8, 7};
        int n = array.length - 1;
        System.out.println("第2小元素为" + search_Kth_Smallest(array, 0, n, 3));
    }

    // 解决
    public static int search_Kth_Smallest(int[] array, int low, int high, int k) {
        int loc = randomPartition(array, low, high); //随机化快排一次后获取的主元素位置
        int i = loc - low + 1;//主元素是此递归小段的第i小元素
        if (i == k)
            return array[loc];
        else if (i > k)
            return search_Kth_Smallest(array, low, loc - 1, k);
        else
            return search_Kth_Smallest(array, loc + 1, high, k - i);
    }

    //随机化主元素,并进行一次快排,返回随机主元素的位置
    public static int randomPartition(int[] array, int low, int high) {
        Random random = new Random();
        int pivotLoc = random.nextInt(high - low + 1) + low;  //把主元素pivot随机化
        swap(array, pivotLoc, high);
        return partition(array, low, high);
    }

    //前后指针法
    public static int partition(int []array,int low,int high) {

        int pivot = array[high];
        int p = low - 1;
        int q = low;

        //利用前后指针,遇到大于主元素的就会拉开二者的距离,故二者之间的元素都是大于pivo的
        for (; q < high - 1; q++) {
            if (array[q] < pivot) {
                p++;
                swap(array, p, q);
            }
        }
        p++;
        swap(array, p, high);
        return  p;
    }

    public static void swap(int arr[], int a, int b) {
        int temp;
        temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

}


你可能感兴趣的:(算法设计与分析)