快速排序QSort详细解析
程序员文章站
2024-03-25 14:31:10
...
笔者在代码中做好了详细注释
package com.ericwei.lib.QuickSort;
import java.util.Arrays;
public class TestQSort {
public static void main(String[] args) {
int[] arr = {5, 4, 6, 1, 9, 7, 3, 2, 8};
qSort(arr, 0, arr.length - 1);
}
/**
* 快速排序的核心思想就是限定中轴
* 将比中轴小的值放到中轴左边
* 比中轴大的值放到中轴右边
* 一次即二分
* 不断二分到最底层
* 时间复杂度nlogn,但由于每次二分无法控制左右平均,所以不稳定
*
* @param arr 需要排序的数据
* @param low 数据左界
* @param high 数据右界
*/
public static void qSort(int arr[], int low, int high) {
/*
1. 限定左界
2. 限定右界
3. 设置中轴,以当前界内第一个值为中轴
*/
int l = low;
int h = high;
int pivot = arr[low];
//如果左界小于右界(说明当前界内元素并未完成二分)
while (l < h) {
//将中轴与右边元素进行比较,如果比中轴大,则放在右边不动
while (l < h && arr[h] >= pivot) {
h--;
}
/*
此时出现了在右边却又比中轴小的元素,即这个元素要被换到中轴左边
这种换法不一定说的是直接将元素插到中轴左边
因为通过l、h限定了未完成分块数据的界,所以只要保证一个相对的位置即可
*/
if (l < h) {
int temp = arr[h];
arr[h] = arr[l];
arr[l] = temp;
//完成交换说明这个l位置已经保证该元素数值比中轴小,即处在正确的分块中了
//则将左界右移动将界缩小
l++;
}
//将中轴与左边元素进行比较,如果比中轴小,则放在左边不动
while (l < h && arr[l] <= pivot) {
l++;
}
//此时出现了在左边却又比中轴大的元素,即这个元素要被换到中轴右边
if (l < h) {
int temp = arr[h];
arr[h] = arr[l];
arr[l] = temp;
h--;
}
/*
因为数据存在一大一小交替的情况,所以一轮分完之后不能保证完成分块
所以需要通过左右界来判断是否完成
未完成的话还需再进行继续的分块工作
*/
}
//完成以当前中轴为中心的大小左右分块后
System.out.println(Arrays.toString(arr));
System.out.print("l=" + (l + 1) + " h=" + (h + 1) + " pivot=" + pivot + "\n");
/*
此时数组是
“[low,l(pivot)]在左,[h(pivot),high]在右”
的形式
*/
if (l > low) {
//如果l>low,说明此次划分左块尚未完成排序
//重新限定左右界继续向下传递
qSort(arr, low, l - 1);
}
if (h < high) {
//如果h<high,说明此次划分右块尚未完成排序
//重新限定左右界继续向下传递
qSort(arr, l + 1, high);
}
}
}
上一篇: Tomcat:安装Tomcat
下一篇: CSS3之动画