算法思路
大概思路:把待排序数组与枢轴值较,大的放在枢轴值右边,小的放在其左边
再分别按上述步骤递归左边部分和右边部分,当左指针
快速排序算法的时间复杂度取决于递归的深度,最坏的情况是n^2
1.创建两个指针,左指针和右指针和一个基准值,当左指针>右指针,退出递归;左指针指向最左边的值,右指针指向最右边的值,基准值为第一个数
//递归结束条件
if (low>high){
return;
}
int l,r,pivot;//左右哨兵和枢轴值
l = low;
r = high;
//枢轴值,每次指定为该组的第一个数
pivot = arr[low];
//循环,知道两个哨兵相遇
//表示pivot到了正确的位置
2.左指针向右遍历,直到找到大于枢轴值的数,右指针向左遍历,直到找到小于枢轴值的数,然后交换两个值
//循环,直到两个哨兵相遇
//表示pivot到了正确的位置
while (l < r){
//先看右边,依次往左递减
//先从右往左找一个小于 基准位的数
//当右边的哨兵位置所在的数>基准位的数 时
//继续从右往左找(同时 j 索引-1)
//找到后会跳出 while循环
while (arr[r] >= pivot && l < r){
r--;
}
//再看左边,依次往右递增
//步骤和上面类似
while (arr[l] <= pivot && l < r){
l++;
}
if (l < r){
//临时变量,用于交换数据
// 左右哨兵 交换数据(互相持有对方的数据)
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
}//while
//这时 跳出了 “while (i<j) {}” 循环
//说明 i=j 左右在同一位置
//最后将基准为与i和j相等位置的数字交换
//让枢轴值到左部份和右部份的中间
arr[low] = arr[l];
arr[l] = pivot;
3.递归枢轴值的左边和右边
//到这里 i=j
//这时 左半数组<(i或j所在索引的数)<右半数组
//也就是说(i或j所在索引的数)已经确定排序位置, 所以就不用再排序了,
// 只要用相同的方法 分别处理 左右数组就可以了
quickSort(arr,low,l-1);
quickSort(arr,l+1,high);
完整的代码
/**
* 快速排序
* @param arr 待排序数组
* @param low 最左边数据的索引
* @param high 最右边数据的索引
*/
public static void quickSort(int[] arr,int low,int high){
//递归结束条件
if (low>high){
return;
}
int l,r,pivot;//左右哨兵和枢轴
l = low;
r = high;
//枢轴值,每次指定为该组的第一个数
pivot = arr[low];
//循环,直到两个哨兵相遇
//表示pivot到了正确的位置
while (l < r){
//先看右边,依次往左递减
//先从右往左找一个小于 基准位的数
//当右边的哨兵位置所在的数>基准位的数 时
//继续从右往左找(同时 j 索引-1)
//找到后会跳出 while循环
while (arr[r] >= pivot && l < r){
r--;
}
//再看左边,依次往右递增
//步骤和上面类似
while (arr[l] <= pivot && l < r){
l++;
}
if (l < r){
//临时变量,用于交换数据
// 左右哨兵 交换数据(互相持有对方的数据)
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
}//while
//这时 跳出了 “while (i<j) {}” 循环
//说明 i=j 左右在同一位置
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[l];
arr[l] = pivot;
//到这里 i=j
//这时 左半数组<(i或j所在索引的数)<右半数组
//也就是说(i或j所在索引的数)已经确定排序位置, 所以就不用再排序了,
// 只要用相同的方法 分别处理 左右数组就可以了
quickSort(arr,low,l-1);
quickSort(arr,l+1,high);