原文地址:xeblog.cn/articles/17数组
快速排序使用的是
分治思想
,经过一趟排序将要排序的数据分割成独立的两部分,其中一部分的全部数据都比另一部分的全部数据都要小,而后再按此方法对这两部分数据分别进行快速排序,整个排序过程能够递归进行,以此达到整个数据变成有序序列。bash
k
,通常取数组第一个元素,以此值分割数组;i
和 j
,i
指向数组的最低位
,j
指向数组的最高位
;j
开始从数组最高位
往数组最低位
(j--)扫描比 k
小的值,扫描到后中止扫描,并将该值填入 i
所处的位置,而后再由 i
开始从数组最低位
往数组最高位
(i++)扫描比 k
大的值,扫描到后中止扫描,并将该值填入 j
所处的位置,j
和 i
依次扫描,直至 j
与 i
的位置相互重合后,将 k
的值填入重合处,此时,数组左侧的值均小于 k
,右侧值均大于 k
,完成这次排序;演示图 测试
/** * 快速排序 * @param array 待排序数组 * @param begin 起点索引 * @param end 终点索引 */
private static void fastSort(int[] array, int begin, int end) {
// 递归终止条件,起点索引大于等于终点索引
if (begin >= end) {
return;
}
// 起点索引
int i = begin;
// 终点索引
int j = end;
// 基准值
int k = array[begin];
// 循环条件:起点索引小于终点索引
while (i < j) {
/* 这个循环是要扫描小于基准值的值,扫描到后退出循环, 循环条件:当前索引位的值大于等于基准值k(加等于号是防止相同数字交换而陷入死循环中), 且起点索引小于终点索引(防止数组下标出界) */
while (array[j] >= k && i < j) {
// 终点索引位从右至左逐个递减
j--;
}
if (i < j) {
// 将小于基准值的数移至左侧
array[i] = array[j];
}
/* 这个循环是要扫描大于基准值的值,扫描到后退出循环, 循环条件:当前索引位的值小于等于基准值k(加等于号是防止相同数字交换而陷入死循环中), 且起点索引小于终点索引(防止数组下标出界) */
while (array[i] <= k && i < j) {
// 起点索引位从左至右逐个递增
i++;
}
if (i < j) {
// 将大于基准值的数移至右侧
array[j] = array[i];
}
}
if (array[j] != k) {
// 基准值归位(数组的中间某个位置),归位后,基准值左侧都是小于基准值的数,右侧都是大于基准值的数
array[j] = k;
}
// 递归将基准值左侧的数排序
fastSort(array, begin, j - 1);
// 递归将基准值右侧的数排序
fastSort(array, j + 1, end);
}
复制代码
测试排序spa
int[] array = {5, 6, 6, 4, 3, 5, 5};
System.out.println("排序前:" + Arrays.toString(array));
fastSort(array, 0, array.length - 1);
System.out.println("排序后:" + Arrays.toString(array));
复制代码
输出结果code
排序前:[5, 6, 6, 4, 3, 5, 5]
排序后:[3, 4, 5, 5, 5, 6, 6]
复制代码
平均时间复杂度: O(nlogn)
。
最坏时间复杂度: O(n^2)
,这种状况发生在排序数组为正序
或逆序
的时候。
稳定性: 不稳定。cdn