快速排序

基本思想:

选取一个基数(通常为第一个或者最后一个), 在一次遍历中不断的比较和交换, 把比基数小的数字都交换到基数的左部, 比基数大的都交换到右部, 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

最好最坏时间复杂度:
最好:

快速排序最“快”的地方在于左右两边能够快速同时递归排序下去,所以最优的情况是基准值刚好取在无序区的中间,这样能够最大效率地让两边排序,同时最大地减少递归划分的次数。此时的时间复杂度仅为 O(NlogN)


最坏:

快速排序也有存在不足的情况,当每次划分基准值时,得到的基准值总是当前无序区域里最大或最小的那个元素,这种情况下基准值的一边为空,另一边则依然存在着很多元素(仅仅比排序前少了一个),此时时间复杂度为 O(N*N)

在这里插入图片描述


从上面我们可以知道, 快速排序的关键在于对 基数 的选取.



java实现


/**
 * @author djh on  2019/5/28 17:34
 * @E-Mail 1544579459@qq.com
 */
public class QuickSort {

    public static void main(String[] args) {
        int[] nums = new int[]{2, 3, 4, 5, 6, 7, 84, 1, 22, 3, 77, 442, 1, 99, 112, 908, 56};
        quickSort(nums, 0, nums.length - 1);
        System.out.println(Arrays.toString(nums));
    }

    public static void quickSort(int[] nums, int left, int right) {

        if (left > right) {
            return;
        }

        int l = left;
        int r = right;
        // 选取最左边的为基数.
        int base = nums[left];
        
        while (l != r) {
            // 从右边开始找, 一直找到一个比基数小的数便停下来
            while (r > l && nums[r] >= base) {
                r--;
            }

            // 然后从左边开始找, 一直找到一个比基数大的数便停下来
            while (l < r && nums[l] <= base) {
                l++;
            }

            // 交换这两个变量
            if (l < r) {
                
                // 使用异或交换两个变量, 需要注意这两个变量不能相等, 不然异或后结果为 0 
                nums[l] ^= nums[r];
                nums[r] ^= nums[l];
                nums[l] ^= nums[r];
            }
            
            // 如果 left 还不等于 right, 说明还未遍历完, 进行下一次循环.
        }

        
        // 最后把基数和 l 与 r 指针相碰撞的位置的数相互交换.
        // 比较迷的是为什么能确定此时 l 位置的数一定比基数小?
        // 想想上面的循环过程就明白了, 我们每次在进行交换后, 此时 l 所指向的这个数一定小于等于基数,
        // 然后进行下一次循环, 又不断的从右边开始找, 假设右边的数都比基数大, 那么 r 会一直走到和 l 相
        // 碰撞才会停下来, 然后退出循环, 交换基数和 l 所指向的数, 所以此时 l 指向的数必定小于等于基数.
        int temp = nums[left];
        nums[left] = nums[l];
        nums[l] = temp;

        // 递归对左右两个部分分别进行排序.
        quickSort(nums, left, l - 1);
        quickSort(nums, l + 1, right);
    }
}

输出:

[1, 1, 2, 3, 3, 4, 5, 6, 7, 22, 56, 77, 84, 99, 112, 442, 908]

Process finished with exit code 0


参考:
教你学习快速排序算法-程序员必备哦
https://blog.csdn.net/jianyuerensheng/article/details/51258374
https://blog.csdn.net/IT_ZJYANG/article/details/53406764

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值