快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
总的来说,快速排序的思想可以分为以下三步:
1. 从待排序元素序列中选取一个数作为基准(一般情况下我们会选取第一个数)。
2. 将比基准大的数全部放在基准右边,将比基准小的数全部放在基准左边。
3. 对左右区间重复执行第一步,第二步,直到每个区间只剩下一个数(递归实现)。
下图是一趟快速排序的实现过程:
(图画的不好昂,代码中注释挺多的QAQ)
在左半边序列将新的基准设置为48,在右半边序列将新的基准设置为83,重复执行,直到所有的元素都是有序的即可。
以下为代码实现:
import java.util.Arrays;
/**
* Created with InteIIiJ IDEA.
* Description:
* User:
* Date:2019-07-17
* Time:23:58
*/
public class Test {
//一趟快速排序
//返回最终low = high 的索引
private static int partition(int[] array, int low, int high) {
int tmp = array[low];//将第一个数据作为基准,
while (low < high) {
//在右边寻找比基准小的数,如果没找到,high--
while (low < high && array[high] >= tmp) {
high--;
}
if (low > high) {
break;
} else {
//如果找到了,将对应high下标的数据放在low下标的位置
array[low] = array[high];
}
//在左边寻找比基准大的数据,如果没找到,low++
while (low < high && array[low] <= tmp) {
low++;
}
if (low >= high) {
break;
} else {
//如果找到了,将对应low下标的数据放在high下标的位置
array[high] = array[low];
}
}
//退出循环的时候基准在相应位置,基准左边的数据都比基准小,右边的数据都比基准大
//将基准放在low或者high的位置(此时low和high相等)
array[low] = tmp;//array[high] = tmp;
return low;
}
//一趟快速排序结束,使得对应基准左边的数据都比基准小,右边的数据都比基准大
//递归调用一趟快速排序,对基准两边的数据进行快速排序
//start:对应需要排序的数组最左边
//end:对应需要排序的数组最右边
private static void sort(int[] array, int start, int end) {
//par:一趟快速排序得到的基准位置的索引
//对基准两边的数据进行快速排序
int par = partition(array, start, end);
if (par > start + 1) {
sort(array, start, par - 1);
}
if (par < end - 1) {
sort(array, par + 1, end);
}
}
public static void quickSort(int[] array) {
//low:左边的对应的索引
int low = 0;
//high:右边的对应的索引
int high = array.length - 1;
sort(array, low, high);
}
public static void main(String[] args) {
int[] array = {72, 6, 57, 88, 60, 42, 83, 73, 48, 85};
//输出排序前
System.out.println("排序前: " + Arrays.toString(array));
//进行快速排序
quickSort(array);
//输出排序后
System.out.println("排序后: " + Arrays.toString(array));
}
}
测试用例:[72, 6, 57, 88, 60, 42, 83, 73, 48, 85]
运行结果:
排序前: [72, 6, 57, 88, 60, 42, 83, 73, 48, 85]
排序后: [6, 42, 48, 57, 60, 72, 73, 83, 85, 88]
Process finished with exit code 0
到这里我们完成了快速排序实现。
快速排序的时间复杂度:N*logN。
快速排序的空间复杂度:logN。
快速排序的稳定性:不稳定。
快速排序的优化:由于直接插入排序有个特点:越有序越快。所以在一定区间内使用直接插入排序会提高排序效率。
快速排序是冒泡排序的改进版,也是最好的一种内排序,涉及到分治和递归。希望大家都能很好的掌握。
祝好!!!