注:该篇文章已与我的个人博客同步更新。欢迎移步https://cqh-i.github.io/体验更好的阅读效果。
快速排序通过将一个数组划分成两个子数组, 然后通过递归调用自身为每一个子数组进行快速排序来实现.
设定关键字(基准数), 将比关键字小的放在一组, 比关键字大的放在另一组.
下面将以数组[6,1,2,7,9,3,4,5,10,8]为例, 演示排序过程
最坏:O(n^2)
平均: O(nlogn)
不稳定, 比如序列为 (5, 3, 3, 4, 3, 8, 9, 10, 11), 第一轮中, 基准数5和第5位置的3交换, 就会破坏稳定性
public class QuickSort {
/** * @Description: 快速排序 * @param arr 待排序的数组 * @param left 从什么位置开始排序 * @param right 排到哪个位置 * @return: void */
public static void quickSort(int[] arr, int left, int right) {
// 数组合法性检测, 递归出口
if (left > right)
return;
// 定义基准数
int base = arr[left];
// 定义变量i, 指向最左边
int i = left;
// 定义变量j, 指向最右边
int j = right;
// 当i和j不相遇的时候, 在循环中检索
while (i != j) {
// 向量j从右往左检索比基准数小的, 如果检索到比基准数小的, 就停下.
while (arr[j] >= base && i < j) {
j--; // j从右往左移动
}
// i 从左往右检索
while (arr[i] <= base && i < j) {
i++; // i 从左往右移动
}
// i停下了, j也停下, 交换两个位置的元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 如果i和j相遇了, 就交换基准数和相遇位置的元素
arr[left] = arr[i];
arr[i] = base;
// 基准数在这里就归位了, 左边的数字都比它小, 右边的数字都比它大.
// 排基准数左边的数组
quickSort(arr, left, i - 1);
// 排基准数右边的数组
quickSort(arr, j + 1, right);
}
public static void main(String[] args) {
int[] arr = new int[] { 6, 1, 2, 7, 9, 3, 4, 5, 10, 8 };
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}
int Partition(int L[], int low, int high)//对子表进行一趟排序,返回枢轴位置
{//L[0]闲置或用作哨兵单元
L[0] = L[low];
int pivotkey = L[low];
while(low < high)
{
while(low < high && L[high] >= pivotkey) --high;
L[low] = L[high];
while(low < high && L[low] <= pivotkey) ++low;
L[high] = L[low];
}
L[low] = L[0];
return low;
}
void Qsort(int L[], int low, int high)
{//L[0]闲置,调用前置初值 low = 1, high = L的length;
if(low < high)
{
int pivotloc = Partition(L, low ,high);//pivotloc是枢轴位置
Qsort(L, low, pivotloc - 1);
Qsort(L, pivotloc + 1, high);
}
}
如果L[0]上面有数字(不闲置),稍微改动一下就可以了
int Patition(int L[], int low, int high)
{
int temp = L[low];
while(low < high)
{
int pivotkey = L[low];
while(low < high && L[high] >= pivotkey)high--;
L[low] = L[high];
while(low < high && L[low] <= pivotkey)low++;
L[high] = L[low];
}
L[low] = temp;
return low;
}
void Qsort(int L[], int low, int high)
{//调用前置low = 0, high = L.length - 1
if(low < high)
{
int pivotloc = Patition(L, low, high);
Qsort(L, low, pivotloc - 1);
Qsort(L, pivotloc + 1, high);
}
}