最基础的快速排序
public class 快速排序test {
public static void main(String[] args) {
int a[]=new int[]{1,3,6,9,14,0,89,4,5};
if(a != null && a.length>=2){
quickSort(a,0,a.length-1);
}
System.out.println(Arrays.toString(a));
}
private static void quickSort(int arr[],int start, int end){
if(start>=end){
return;
}
int left = start;
int right = end;
int temp = arr[right];//选用最右边节点作为参考点
while(left<right){
//从两边开始遍历 因为选取的是右边节点,所以先从左边开始遍历
while(arr[left]<temp&&left<right){
left++;
}
while(arr[right]>=temp&&left<right){
right--;
}
swap(arr, left, right);
}
//交换参考点和right 把参考点换到中间
swap(arr,right,end);
quickSort(arr, start, right-1 );
quickSort(arr, right+1,end);
}
private static void swap(int arr[], int left, int right){
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
可以从很多方面做优化
比如 从参考点选取方面 每次随机选取一个做参考点
再比如这样每次循环只能确定一个数的位置 就算中间的数字重复 也是只能确定一个
比如 5 , 1 , 5, 2, 5 , 6, 7 , 5
只能确定一个5 的位置 其余的5还会参与下次循环。
修改调换位置的算法 使得一次能确定所有的5
参考荷兰国旗问题
public class 快速排序test2 {
public static void main(String[] args) {
int a[]=new int[]{1,3,6,9,14,0,89,4,5};
if(a != null && a.length>=2){
quickSort(a,0,a.length-1);
}
System.out.println(Arrays.toString(a));
}
private static void quickSort(int arr[],int start, int end){
if(start>=end){
return;
}
swap(arr, start+new Random().nextInt(end-start+1),end);
int[] p =partition(arr, start, end); //p[0] 代表中间相等的参考值数组左下标 p[1]代表中间相等的参考值数组右下标
quickSort(arr, start, p[0]-1 );
quickSort(arr, p[1]+1,end);
}
private static int[] partition(int arr[],int l, int r){
int less = l-1; //左边界
int more = r; //右边界
while(l < more){
if(arr[l] < arr[r]){ //如果小于参考值 和左边界下一位交换 左边界扩大一位 l向右移动
swap(arr, ++less, l++);
}else if(arr[l] > arr[r]){ //如果大于参考值 和右边界前一位交换 右边界向左扩大一位 由于从右边界换来的数大小不确定 所以l再做判断
swap(arr, --more, l);
}else{ //如果等于参考值 l向右边移动
l++;
}
}
swap(arr, more, r); //交换参考值和右边界的值
return new int[]{less+1,more};
}
private static void swap(int arr[], int left, int right){
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}