快速排序QSort详细解析

笔者在代码中做好了详细注释

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);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值