基本思想 :
选择最后一个数组元素作为 基准值
排序将基准值的左区间 都放 小于基准值的元素 ;基准值右区间 都放 大于基准值的元素
将以上操作应用在 以基准值为分界线的 左区间 和 右区间
非递归版本:
栈里存放 要处理的区间范围的下标
-
将 下标
0和arr.length - 1入栈 -
循环出栈:出栈
2个栈顶元素 就是 要处理的区间下标 -
调用
partition分隔区间 得到2个子区间a) 得到的子区间只有
1个 或0个元素 不入栈(不处理)b) 有更多的内容再入栈 子区间
-
直到栈为空,排序完成
代码实现
java
public static void quickSort(int[] arr) {
//区间采用左闭右闭
quickSortHelper(arr,0,arr.length-1);
}
private static void swap(int[] arr, int index1, int index2) {
int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
private static int partition(int[] arr,int left,int right){
int l = left;
int r = right;
//设置基准值 为当前区间的右边(下标为 right)的数组元素
int value = arr[right];
while (l < r) {
//左边找比基准值大的数字
while(l < r && arr[l] < value) {
l++;
}
//右边找小于基准值的数字 不包括基准值 所以是 >=
while(l < r && arr[r] >= value) {
r--;
}
swap(arr, l, r);
}
//l r相遇时的下标的数组元素 和 基准值 交换
swap(arr, l, right);
//返回基准值的下标
return l;
}
private static void quickSortHelper(int[] arr,int left,int right) {
//left == right 是只有一个元素
//left > right 是没有元素
//如果得到的区间只有 1 个 或 0 个元素 不处理
if(left >= right){
return;
}
int index = partition(arr,left,right);
//[left index - 1]
quickSortHelper(arr,left,index-1);
//[index+1 right]
quickSortHelper(arr,index+1,right);
}
//快速排序的非递归版本
public static void qickSortByLoop(int[] arr){
Stack<Integer> stack = new Stack<>();
//栈里存放的是 排序范围的下标
stack.push(0);
stack.push(arr.length-1);
while(!stack.isEmpty()){
//取出要处理的区间
int right = stack.pop();
int left = stack.pop();
//如果得到的区间只有 1 个 或 0 个元素 不处理
if(left >= right){
continue;
}
int index = partition(arr,left,right);
//内容更多再处理
stack.push(index + 1);
stack.push(right);
stack.push(left);
stack.push(index - 1);
}
}