前言
快速排序(Quick Sort)算法和冒泡排序算法类似,都是基于交换排序的思想。快速排序算法对冒泡排序算法进行了改进,从而具有更高的执行效率。而且也是面试常考的一种算法,不仅得会写,更主要的是理解其中的思想。
快速排序的流程
(1)首先设定一个分界值,通过该分界值将数组分为左右两部分
(2)将大于等于分界值的数据集中到数组的右边,小于分界值的数据集中到数组的左边,此时左边部分中各元素都小于等于分界值,右边部分中各元素都大于分界值
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样将左边放置较小值,右边放置较大值。右侧的数组也做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好后,再递归排好右侧部分的顺序。当左、右两部分各数据排序完成后,整个数组的排序也就完成了
详细代码
上面的流程,一般看完后会懵懵懂懂,结合下面的代码,然后慢慢理解
public class MyQuickSort {
static final int SIZE = 18;
/**
* @param arr 待排序的数组
* @param left 数组的左边界(例如,从起始位置开始排序,则left=0)
* @param right 数组的右边界(例如,排序截至到数组末尾,则right=arr.length-1)
*/
private static void quickSort(int[] arr, int left, int right) {
int f, t;//f是分界值,t是后面要进行交换的临时temp变量
int rtemp, ltemp;//左、右数组临时变量
ltemp = left;//由于要一直移动指针(索引),因此要定义左右两侧的临时指针(索引)变量
rtemp = right;
f = arr[(left + right) / 2];//分界值
while (ltemp < rtemp) { //确保左边的索引要小于右边(因为我们左边放比分界值小的值,右边放比分界值大的值)
//只有等左边的值小于分界值,我们的指针才会继续向右移动,
// 否则,指针就指这个值,等待和右边的值交换
while (arr[ltemp] < f) {
++ltemp; // 指针向右移动
}
//只有等右边的值大于于分界值,我们的指针才会继续向左移动,
// 否则,指针就指这个值,等待和左边的值交换
while (arr[rtemp] > f) {
--rtemp;// 指针向左移动
}
//程序走早这里,一定是出现,左侧指针指向了大于分界值的数据,右侧指针指向了小于分界值的数据
if (ltemp <= rtemp) { // 依然是确保左边的索引要小于右边(因为我们左边放比分界值小的值,右边放比分界值大的值)
//交换两个数据,也就是把右边小于分界值的数据和左边大于分界值的数据进行交换,
// 这样就可以做到左边永远都小于分界值,右边永远都大于分界值
t = arr[ltemp];
arr[ltemp] = arr[rtemp];
arr[rtemp] = t;
++ltemp;//交换完后,左侧的指针向右侧移动一位
--rtemp; //交换完后,右侧的指针向左侧移动一位
}
}
if (ltemp == rtemp) {
ltemp++;
}
//确保右侧的指针向左移动不能超过数组左侧索引
if (left < rtemp) {
//此时left依然不变,而right的位置已经变为ltemp-1
quickSort(arr, left, ltemp - 1);//递归调用
}
//确保左侧的指针向右移动不能超过数组右侧索引
if (ltemp < right) {
//此时right依然不变,而left的位置已经变为rtemp+1
quickSort(arr, rtemp + 1, right);//递归调用
}
}
public static void main(String[] args) {
int[] arr = new int[SIZE];
int i;
for (i = 0; i < SIZE; i++) {
arr[i] = (int) (100 + Math.random() * (100 + 1));//初始化数组
}
System.out.print("排序前的数组为:\n");
for (i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
quickSort(arr, 0, arr.length - 1);//排序操作;
System.out.print("排序后数组为:\n");
for (i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " "); //输出排序后的数组
}
System.out.println();
}
}
运行结果:
排序前的数组为:
131 167 177 163 120 110 109 158 161 190 102 148 193 188 120 169 140 169
排序后数组为:
102 109 110 120 120 131 140 148 158 190 161 163 167 169 169 177 188 193
后记
一定要理解什么情况下左侧需要和右侧数据进行交换
来源:CSDN
作者:SunnyRivers
链接:https://blog.csdn.net/Android_xue/article/details/103646043