package leo.class03_05; import leo.util.ArrayUtil; import java.util.Arrays; import java.util.Stack; /** * @author Leo * @ClassName QuickSort1 * @DATE 2020/11/26 11:17 上午 * @Description 快排1.0 * O(N²) 最差情况 * 范围内最后一个数为比较值x,[<=x>],x一定在左侧的最后一个位置,返回比较值得下标 * 只记录右侧最小位置下标,如果index的值小于或等于右侧最后位置的数, * index与最小位置的数后一位交换,最小位置下标更新 * * T(N) = a * T(N/b) + O(N^d)(其中的a、b、d都是常数) * 的递归函数,可以直接通过Master公式来确定时间复杂度 * 如果 log(b,a) < d,复杂度为O(N^d) * 如果 log(b,a) > d,复杂度为O(N^log(b,a)) * 如果 log(b,a) == d,复杂度为O(N^d * logN) * */ class QuickSort1 { public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } private static void process(int[] arr, int l, int r) { if (l >= r) { return; } int m = partition(arr, l, r); process(arr, l, m-1); process(arr, m + 1, r); } private static int partition(int[] arr, int l, int r) { if (l > r) { return -1; } if (l == r) { return l; } int less = l-1; int index = l; while (index < r) { if (arr[index] <= arr[r]) { swap(arr, index, ++less); } index++; } swap(arr, r, ++less); return less; } private static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } /** * @author Leo * @ClassName QuickSort1 * @DATE 2020/11/26 11:17 上午 * @Description 快排2.0 * O(N²) 最差情况 * 中间位置固定,左右两边有序 * */ class QuickSort2 { public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } public static void process(int[] arr, int l, int r) { if (l >= r) { return; } int[] equalsArea = partition(arr, l, r); process(arr, l, equalsArea[0] - 1); process(arr, equalsArea[1] + 1, r); } //netherlandsFlag //荷兰国旗问题 private static int[] partition(int[] arr, int l, int r) { if (l > r) { return new int[]{-1, -1}; } if (l == r) { return new int[]{l, r}; } int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); }else{ index++; } } swap(arr, r, rightIndex); return new int[]{leftIndex+1, rightIndex}; } private static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } /** * @author Leo * @ClassName QuickSort1 * @DATE 2020/11/26 11:17 上午 * @Description 快排3.0 * O(N*logN) * 额外空间复杂度o(n) * */ class QuickSort3 { public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } public static void process(int[] arr, int l, int r) { if (l >= r) { return; } swap(arr, (int) (l + (Math.random() * (r - l + 1))), r); int[] equalArea = partition(arr, l, r); process(arr, l, equalArea[0] - 1); process(arr, equalArea[1] + 1, r); } public static int[] partition(int[] arr, int l, int r) { if (l > r) { return new int[]{-1, -1}; } if (l == r) { return new int[]{l, r}; } int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] == arr[r]) { index++; } else if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); } } swap(arr, r, rightIndex); return new int[]{leftIndex + 1, rightIndex}; } public static void swap(int[] arr, int i, int j) { if (arr[i] == arr[j] || i == j) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } class QuickSort3_1{ public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } private static void process(int[] arr, int l, int r) { if (l >= r) { return; } swap(arr, (int) (l + ((r - l + 1) * Math.random())), r); int[] equalArea = partition(arr, l, r); process(arr, l, equalArea[0] - 1); process(arr, equalArea[1] + 1, r); } private static int[] partition(int[] arr, int l, int r) { if (l == r) { return new int[]{l, r}; } int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] == arr[r]) { index++; } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); } else if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } } swap(arr, r, rightIndex); return new int[]{leftIndex + 1, rightIndex}; } public static void swap(int[] arr, int i, int j) { if (arr[i] == arr[j] || i == j) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } class QuickSort3_2{ public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } public static void process(int[] arr, int l, int r) { if (l >= r) { return; } swap(arr, (int) (l + ((r - l + 1) * Math.random())), r); int[] equalArea = partition(arr, l, r); process(arr, l, equalArea[0] - 1); process(arr, equalArea[1] + 1, r); } private static int[] partition(int[] arr, int l, int r) { if (l == r) { return new int[]{l, r}; } int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] == arr[r]) { index++; } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); } else if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } } swap(arr, r, rightIndex); return new int[]{leftIndex + 1, rightIndex}; } private static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } class QuickSort3_3{ public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } private static void process(int[] arr, int l, int r) { if (l >= r) { return; } int[] equalArea = partition(arr, l, r); process(arr, l, equalArea[0] - 1); process(arr, equalArea[1] + 1, r); } public static int[] partition(int[] arr, int l, int r) { if (l > r) { return new int[]{-1, -1}; } if (l == r) { return new int[]{l, r}; } int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] == arr[r]) { index++; } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); } else if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } } swap(arr, r, rightIndex); return new int[]{leftIndex + 1, rightIndex}; } public static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } class QuickSort3_4{ public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } process(arr, 0, arr.length - 1); } public static void process(int[] arr, int l, int r) { if (l >= r) { return; } int[] equalArea = partition(arr, l, r); process(arr, l, equalArea[0] - 1); process(arr, equalArea[0] + 1, r); } private static int[] partition(int[] arr, int l, int r) { int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] == arr[r]) { index++; } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); } else if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } } swap(arr, r, rightIndex); return new int[]{leftIndex + 1, rightIndex}; } public static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } class QuickSortUnRecursive{ private static class Op { public int l; public int r; public Op(int l, int r) { this.l = l; this.r = r; } } public static void quickSort(int[] arr) { if (arr.length < 2 || arr == null) { return; } swap(arr, arr.length - 1, (int) (arr.length * Math.random())); int[] equalArea = partition(arr, 0, arr.length - 1); Stack stack = new Stack<>(); int l = equalArea[0] - 1; int r = equalArea[1] + 1; stack.push(new Op(0, l)); stack.push(new Op(r, arr.length - 1)); while (!stack.isEmpty()) { Op pop = stack.pop(); int pl = pop.l; int pr = pop.r; if (pl < pr) { swap(arr, (int) (pl + (Math.random() * (pr - pl + 1))), pr); equalArea = partition(arr, pl, pr); l = equalArea[0] - 1; r = equalArea[1] + 1; stack.push(new Op(pl, l)); stack.push(new Op(r, pr)); } } } public static int[] partition(int[] arr, int l, int r) { if (l > r) { return new int[]{-1, -1}; } if (l==r){ return new int[]{l, r}; } int leftIndex = l - 1; int rightIndex = r; int index = l; while (index < rightIndex) { if (arr[index] == arr[r]) { index++; } else if (arr[index] < arr[r]) { swap(arr, index++, ++leftIndex); } else if (arr[index] > arr[r]) { swap(arr, index, --rightIndex); } } swap(arr, r, rightIndex); return new int[]{leftIndex + 1, rightIndex}; } private static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } } class TestMain { public static void main(String[] args){ int testTimes = 1000; int sizeMax = 50; int range = 50; System.out.println("start"); for (int i = 0; i < testTimes; i++) { int[] arr = ArrayUtil.randomArray(sizeMax, range); int[] copyArray = ArrayUtil.copyArray(arr); QuickSort3_4.quickSort(arr); Arrays.sort(copyArray); if (!ArrayUtil.isEqual(arr, copyArray)) { ArrayUtil.printArr(arr); ArrayUtil.printArr(copyArray); System.out.println("fuck"); break; } } System.out.println("end"); } }