目录
1 快排思想
每次从待排序数码中选取一个“基准值”,将该数码分成两部分,左边的一部分数值都小于该“基准值”,右边的一部分数值都大于该“基准值”,递归算法每次将左右两部分数码再次进行快排,非递归则借助栈实现,具体见以下代码:
2 递归实现代码
递归的优化可以从两方面着手:三数取中法选key和递归到小的区间时采用插入排序
public class Test {
//最后的测试结果:1 2 2 3 4 5 5 6 7 9 22 22 23 23 33 34 44 55 56 56 56 57 66 67 77 88 90 99 345 678
public static void main(String[] args) {
int[] data = new int[]{6,2,4,7,9,3,1,5,22,66,44,55,33,22,77,88,99,90,2,5,56,34,56,678,345,23,23,56,57,67};
quickSort(data,0,data.length-1);
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]+" ");
}
}
//取得基准值
public static int partSort(int[] arr,int low,int high){
int tmp = arr[low];
while (low < high){
//从后往前遍历,找到第一个比arr[low]小的值,并将其赋值在low的位置
while (low<high && arr[high]>=tmp){
high--;
}
if (low>=high){
break;
}else {
arr[low] = arr[high];
}
//从前往后遍历,找到第一个比arr[high]大的值,将其赋值在high的位置
while (low<high && arr[low]<=tmp){
low++;
}
if (low>=high){
break;
}else {
arr[high] = arr[low];
}
}
//最后将基准值赋值到相应位置,并将其下标返回
arr[low] = tmp;
return low;
}
//直接插入排序
public static void insertSort(int[] arr){
for (int i = 1; i < arr.length; i++) {
int tmp = arr[i];
int j = 0;
for (j = i-1; j >= 0 ; j--) {
if (arr[j] > tmp){
arr[j+1] = arr[j];
}else {
break;
}
}
arr[j+1] = tmp;
}
}
public static void swap(int[] arr,int a,int b){
int tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
public static void middleThree(int[] arr,int low,int high){
int mid = (low+high)/2;
if (arr[mid] > arr[low]){
swap(arr,mid,low);
}
if (arr[low] > arr[high]){
swap(arr,low,high);
}
if (arr[mid] > arr[high]){
swap(arr,mid,high);
}
//最后得:arr[mid] <= arr[low] <= arr[high]
}
public static void quickSort(int[] arr,int start,int end){
//如果数组个数小于6,则进行插入排序
if (end-start+1 <= 6){
insertSort(arr);
return;
}
//三数取中选取key
middleThree(arr,start,end);
//取得一次“基准值”
int part = partSort(arr,start,end);
//递归左边
quickSort(arr,start,part-1);
//递归右边
quickSort(arr,part+1,end);
}
}
3 非递归实现代码
import java.util.Stack;
public class Test {
public static void main(String[] args) {
int[] data = new int[]{6,2,4,7,9,3,1,5,22,66,44,55,33,22,77,88,99,90,2,5,56,34,56,678,345,23,23,56,57,67};
quickSort(data);
for (int i = 0;i < data.length;i++){
System.out.print(data[i]+" ");
}
}
public static void quickSort(int[] array) {
//定义一个栈,用于存放low和high
Stack<Integer> stack = new Stack<>();
int low = 0;
int high = array.length-1;
//第一次将基准值取出
int par = partion(array,low,high);
//先进行一次判断,将基准值取出之后判断左右两边的数据个数是否大于2(只有1个数据则
// 说明排序完成),若左右两边的数据个数大于2,则将相应的数据入栈
//注意:将左半部分的数据入栈时,先将low入栈,再将part-1入栈,因为出栈的时候
//先取的是high。
if(par > low+1){
stack.push(low);
stack.push(par-1);
}
if(par < high-1) {
stack.push(par+1);
stack.push(high);
}
//该循环当栈不为空的时候进行
while (!stack.empty()) {
//首先取出栈中的元素,调用一次partion函数
high = stack.pop();
low = stack.pop();
par = partion(array,low,high);
//如果par左边有两个及两个数据以上,则进行入栈操作
if(par > low+1){
stack.push(low);
stack.push(par-1);
}
//如果par右边有两个及两个数据以上,则进行入栈操作
if(par < high-1) {
stack.push(par+1);
stack.push(high);
}
}
}
public static int partion(int[] array,int low,int high) {
int tmp = array[low];
while (low < high) {
while (low < high && array[high] >= tmp) {
high--;
}
if(low >= high) {
break;
}else {
array[low] = array[high];
}
while (low < high && array[low] <= tmp) {
low++;
}
if(low >= high) {
break;
}else {
array[high] = array[low];
}
}
array[low] = tmp;
return low;
}
}