其思路主要是,取得数组的中位数(方式多种,本文采用中间索引为中位数),把数组中小于中位数的放左边,大于中位数的放右边。
之后在分好的左右数组中,使用递归的方式,来执行上述的排序思路。
代码及详细解释如下:
// static int[] list = {9, 4, 0, 8, 5, 7, 6, 2, 3, 1};
static int[] list = new int[80];
static {
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 80);
}
}
/**
* 快速排序
* 其思路主要是,取得数组的中位数(方式多种,本文采用中间索引为中位数),把数组中小于中位数的放左边,大于中位数的放右边。
* 之后在分好的左右数组中,使用递归的方式,来执行上述的排序思路。
*/
public static void main(String[] args) {
long l = System.currentTimeMillis();
quickSort(0, list.length - 1);
long s = System.currentTimeMillis();
System.out.println(s - l);
}
public static void quickSort(int left, int right) {
//确定中位数
int median = (left + right) / 2;
//分段计算
for (int i = median -1 ; i >=left ; i--) {
//左段从尾部开始,如果大于中位数,先把中位数赋值给前一位pre,
//中位数index前移一位,左段循环当前值赋值到中位数的index位置,中位数前一位pre值赋值到左段循环当前值位置
//tips:当左段循环值和中位数前一位pre重合,交换当前循环值和中位数的位置
if (list[i] >= list[median]) {
int pre = median - 1;
int tmp = list[pre];
list[pre] = list[median];
if (i == pre) {
list[median] = tmp;
} else {
list[median] = list[i];
list[i] = tmp;
}
//交换成功后,中位值索引改变
median--;
}
}
for (int i = median + 1; i <= right; i++) {
//左段从中位数下一位开始,如果小于中位数,先把中位数赋值给后一位post,
//中位数index后移一位,右段循环当前值赋值到中位数的index位置,中位数后一位post值赋值到右段循环当前值位置
//tips:当右段循环值和中位数后一位post重合,交换当前循环值和中位数的位置
if (list[i] <= list[median]) {
int post = median + 1;
int tmp = list[post];
list[post] = list[median];
if (i == post) {
list[median] = tmp;
} else {
list[median] = list[i];
list[i] = tmp;
}
//交换成功后,中位值索引改变,但是其索引的后移,不会影响后续循环遍历,所以i无须改变
median++;
}
}
if (median - left > 1) {
quickSort(left, median - 1);
}
if (right - median > 1) {
quickSort(median + 1, right);
}
System.out.println(Arrays.toString(list));
}
经过测试,8w数据排序耗时13ms,1000w数据耗时1.4s。