目录
递归版本
package 数据结构复习.经典排序算法.快速排序;
import java.util.Arrays;
public class 快速排序 {
public static void main(String[] args) {
int[] ints = {1, 9, -2, 8, 89};
quickSort(ints, 0, ints.length - 1);
System.out.println(Arrays.toString(ints));
}
public static void quickSort(int[] arr, int left, int right) {
//1.找到基准值
if (left >= right) {
return;
}
int pivot = partition(arr, left, right);
quickSort(arr, left, pivot - 1);
quickSort(arr, pivot + 1, right);
}
/**
* 递归写法(快速排序)
* @param arr
* @param left
* @param right
* @return
*/
private static int partition(int[] arr, int left, int right) {
//1.记录一下开始的位置
int tmp = left;
int key = arr[tmp];
while (left < right) {
//1先移动右边找到小于 key的值
while (left < right && arr[right] >= key) {
right--;
}
while (left < right && arr[left] <= key) {
left++;
}
swap(arr, left, right);
}
//交换开始的位置 自己画一下图可能会更清楚
swap(arr, left, tmp);
return left;
}
static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
非递归版本
package 数据结构复习.经典排序算法.快速排序;
import java.util.Stack;
public class 快速排序非递归 {
public static void main(String[] args) {
}
public static void quickSort(int[] arr) {
int left = 0;
int right = arr.length - 1;
//1.找到基准值
if (left >= right) {
return;
}
int pivot = partition(arr, left, right);
Stack<Integer> stack = new Stack<>();
//这里是判断是不是有多个 如果中间只有一个值的话也就没有必要放进去了
if (pivot > left + 1) {
stack.push(left);
stack.push(pivot - 1);
}
if (pivot < right - 1) {
stack.push(right);
stack.push(pivot + 1);
}
//开始从里面取值
while (!stack.isEmpty()) {
right = stack.pop();
left = stack.pop();
pivot = partition(arr, left, right);
if (pivot > left + 1) {
stack.push(left);
stack.push(pivot - 1);
}
if (pivot < right - 1) {
stack.push(right);
stack.push(pivot + 1);
}
}
}
/**
* 递归写法(快速排序)
*
* @param arr
* @param left
* @param right
* @return
*/
private static int partition(int[] arr, int left, int right) {
//1.记录一下开始的位置
int tmp = left;
int key = arr[tmp];
while (left < right) {
//1先移动右边找到小于 key的值
while (left < right && arr[right] >= key) {
right--;
}
while (left < right && arr[left] <= key) {
left++;
}
swap(arr, left, right);
}
//交换开始的位置 自己画一下图可能会更清楚
swap(arr, left, tmp);
return left;
}
static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
优化版本
package 数据结构复习.经典排序算法.快速排序;
public class 快速排序优化版 {
/**
* 采用三数取中
* 减少递归的层数(层数很少的时候采取直接插入排序)
*
* @param args
*/
public static void main(String[] args) {
}
public static void quickSort(int[] arr, int left, int right) {
//1.找到基准值
if (left >= right) {
return;
}
if (right - left + 1 <= 7) {
//插入排序 减少递归深度()
insertSort(arr);
return;
}
//三数取中()
int index = midNumIndex(arr, left, right);
swap(arr, index, left);
int pivot = partition(arr, left, right);
quickSort(arr, left, pivot - 1);
quickSort(arr, pivot + 1, right);
}
/**
* 插入排序
*/
private static void insertSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int index = i;
//要处理的值
int tmp = arr[i + 1];
//前面的值都比tmp值要大 那么就往后移动
while (index >= 0 && arr[index] > tmp) {
arr[index + 1] = arr[index];
index--;
}
arr[index + 1] = tmp;
}
}
private static int midNumIndex(int[] arr, int left, int right) {
//1.怎么从三个数中取到中位数
// 6 x 9
int mid = (left + right) / 2;
//假设left 小于 right
if (arr[left] < arr[right]) {
if (arr[mid] < arr[left]) {
return left;
} else if (arr[mid] > arr[right]) {
return right;
} else {
return mid;
}
} else {
if (arr[mid] > arr[left]) {
return left;
} else if (arr[mid] < arr[right]) {
return right;
} else {
return mid;
}
}
}
/**
* 递归写法(快速排序)
*
* @param arr
* @param left
* @param right
* @return
*/
private static int partition(int[] arr, int left, int right) {
//1.记录一下开始的位置
int tmp = left;
int key = arr[tmp];
while (left < right) {
//1先移动右边找到小于 key的值
while (left < right && arr[right] >= key) {
right--;
}
while (left < right && arr[left] <= key) {
left++;
}
swap(arr, left, right);
}
//交换开始的位置 自己画一下图可能会更清楚
swap(arr, left, tmp);
return left;
}
static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}