快排过程:先找一个支点(pivot), 然后一趟排序把数组划分为,左小于<pivot的, pivot点, 右大于>pivot的三部分,然后对左右继续找支点,划分,递归,直到左右完成。看sort(), 就是这个意思
本代码有两种实现快排
-
partition1 实现过程
low high 为要排部分数组收尾,选第一个元素为支点 从数组收尾分别遍历 尾部小于支点的移动到 arr[low] = arr[high] , 前部大于支点的移动到 arr[high] = arr[low] 直到 low与high相等到达中间点遍历完成 把支点放入中间点 arr[low] = pivot 开始下次递归
-
partition2 实现过程
选最后一个数为支点 for循环从头开始遍历,i 记录上次比支点小的数位置,【i++就是上次比支点大的数的位置】 如果比支点小,就把i++位置的数交换,因为 i++就是上次比支点大的数的位置 一趟遍历完,把支点放到中间位置
import java.util.Arrays;
public class Test {
public static void sort(int[] arr, int begin, int end) {
if (begin >= end)
return;
// int pivotIndex = partition1(arr,begin,end);
int pivotIndex = partition2(arr, begin, end);
sort(arr, begin, pivotIndex - 1); //sort left of pivot
sort(arr, pivotIndex + 1, end); //sort right of pivot
}
private static int partition1(int[] arr, int begin, int end) {
int low = begin;
int high = end;
int pivot = arr[low]; // first as pivot
while (low < high) {
while (low < high && arr[high] > pivot) { //pivot is the first, so start from end
high--;
}
arr[low] = arr[high];
while (low < high && arr[low] <= pivot) {
low++;
}
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
}
public static int partition2(int arr[], int begin, int end) {
int pivot = arr[end];
int i = begin - 1; // index of smaller element
for (int j = begin; j < end; j++) {
if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
// pivot to the middle
swap(arr, i + 1, end);
return i + 1;
}
private static void swap(int[] arr, int i, int j) {
if (i == j || arr[i] == arr[j])
return;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int arr[];
int arr1[] = {6, 3, 5, 7, 2, 9, 4, 8, 7};
int arr2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
int arr3[] = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
int arr4[] = {3, 1, 2};
int arr5[] = {3, 7, 8, 5, 2, 1, 9, 5, 4};
arr = arr5;
System.out.println("before sort1:" + Arrays.toString(arr));
Test.sort(arr, 0, arr.length - 1);
System.out.println("after sort1:" + Arrays.toString(arr));
}
}