記錄一個基於Java的利用快排切分來實現快排TopK問題的程式碼模板
阿新 • • 發佈:2020-09-08
使用快排切分實現快排和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