快速排序
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
算法描述
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
- 从数列中挑出一个元素,称为 “基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
代码
package com.example.maventest.scort.quickcort;
import java.util.Arrays;
public class QuickSort3 {
public static void quickSort(int[] arr, int low, int high) {
int i, j, temp, t;
if (low > high) {
return;
}
i = low;
j = high;
//temp就是基准位
temp = arr[low];
while (i < j) {
//先看右边,依次往左递减
while (temp <= arr[j] && i < j) {
j--;
}
//再看左边,依次往右递增
while (temp >= arr[i] && i < j) {
i++;
}
//如果满足条件则交换
if (i < j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
// 这时候,跳出上面大的while循环之后,i和j肯定是相等的,因为上面循环的条件是i<j,所以,跳出循环时,i和j是相等的
/**
* 假如最好的情况是一个有序序列 1 3 5 7 9
* temp = 1
* i = 0 arr[i] = 1
* j = 4 arr[j] = 9
* 而且在这里,如果先从左边开始寻找的话,一直往右寻找大于1的数,直到i变成4还没有找到就停止了;但是下面的语句就会把9赋值在1上了
* 如果先从右边开始寻找的话,一直往左寻找小于1的数,直到j变成0还没有找到然后停止,此时i和j都是0,所以就是把自身交换一下并不影响顺序。
* 这也是为什么强调如果选择数组左边第一个数作为基准值的时候,得先从右边开始查找数。
*/
// 最后将基准位与i和j相等位置的数字交换
// 下面的i和j其实相等的,所以用哪一个都一样。
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j - 1);
//递归调用右半数组
quickSort(arr, j + 1, high);
}
public static void main(String[] args) {
int[] arr = {10, 17, 21, 46, 7, 62, 3, 4, 2, 1, 8, 9, 19};
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}