1. 程式人生 > 實用技巧 >記錄一個基於Java的利用快排切分來實現快排TopK問題的程式碼模板

記錄一個基於Java的利用快排切分來實現快排TopK問題的程式碼模板

使用快排切分實現快排和TopK問題的解題模板

import java.util.Arrays;

public class TestDemo {
    public static void main(String[] args) {
        int[] arr1 = {48, 12, 6 ,8, 11};
        int[] arr2 = {25, 14, 45 ,8, 10};
        int k = 2;
        System.out.print("Array_1: ");
        printArr(arr1);
        System.out.print("GetTopK: ");
        // 注意是k-1
        int[] topK = getTopK(arr1, 0, arr1.length - 1, k - 1);
        printArr(topK);
        System.out.print("Array_2: ");
        printArr(arr2);
        quickSort(arr2, 0, arr2.length - 1);
        System.out.print("Sorted:  ");
        printArr(arr2);
    }

    /**
     * 快速排序
     * @param arr 陣列
     * @param l 左邊界
     * @param r 右邊界
     */
    private static void quickSort(int[] arr, int l, int r) {
        if (l >= r) return;
        int index = partition(arr, l, r);
        quickSort(arr, l, index - 1);
        quickSort(arr, index + 1, r);
    }

    /**
     * 快排切分尋找TopK
     * @param arr 陣列
     * @param l 左邊界
     * @param r 右邊界
     * @param k TopK
     * @return TopK陣列
     */
    private static int[] getTopK(int[] arr, int l, int r, int k) {
        // 每快排切分1次,找到排序後下標為j的元素,如果j恰好等於k就返回j以及j左邊所有的數
        int j = partition(arr, l, r);
        if (j == k) return Arrays.copyOf(arr, j + 1);
        // 否則根據下標j與k的大小關係來決定繼續切分左段還是右段
        return j > k ? getTopK(arr, l, j - 1, k) : getTopK(arr, j + 1, r, k);
    }

    /**
     * 快排切分
     * 返回下標j,使得比arr[j]小的數都在j的左邊,比arr[j]大的數都在j的右邊
     * @param arr 陣列
     * @param l 左邊界
     * @param r 右邊界
     * @return 一次切分後的基準值下標j
     */
    private static int partition(int[] arr, int l, int r) {
        int i = l, j = r + 1, pivot = arr[l];
        while (true) {
            while (++i <= r && arr[i] < pivot);
            while (--j >= l && arr[j] > pivot);
            if (i >= j) break;
            swap(arr, i, j);
        }
        swap(arr, l, j);
        return j;
    }

    /**
     * 陣列下標對應值交換函式
     * @param arr 陣列
     * @param i 下標i
     * @param j 下標j
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * 列印陣列
     * @param arr 陣列
     */
    private static void printArr(int[] arr) {
        for (int i : arr) {
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

輸出結果

Array_1: 48 12 6 8 11 
GetTopK: 6 8 
Array_2: 25 14 45 8 10 
Sorted:  8 10 14 25 45