【算法面试宝典】十大经典排序算法 - 快速排序

2.3.1 解题思路

        快速排序的核心思想是找到一个目标值 key ,使用数组 nums 中的元素和 key 进行比较,大于 key 的元素放到数组的一边,小于 key 的元素放到数组的另一边,这样 key 的位置就确定了,依次使用这种方式对两边的数组进行排序,最终得到排好序的数组。

示例:

输入 nums = {4,8,1,5,9,2}    输出 nums = {1,2,4,5,8,9}

快速排序执行步骤:

初始化:nums = {4,8,1,5,9,2}

第一步:nums = {4,8,1,5,9,2}

              选定最左边的元素 4 作为目标值。先从左边开始比较,8 大于 4 ,所以 leftIndex 指针停留在指向 8 的位置,值为 1。

第二步:nums = {4,2,1,5,9,8}

               从右边比较,2 小于 4 ,所以 rightIndex 指针停留在指向 2 的位置,值为 5。交换 下标 0 和 5 的值。

第三步:nums = {4,2,1,5,9,8}

               继续从左边开始比较,1 小于 4,leftIndex--,指针指向 5,5 大于 4,所以 leftIndex 停留在 5 的位置,leftIndex = 3 。

第四步:nums = {4,2,1,5,9,8}

               继续从右边比较,8,9都大于 4 ,rightIndex最后也指向 5 。

第五步:nums = {1,2,4,5,9,8}

               判断 5 大于 4 ,所以交换 leftIndex-1 位置 和 key 位置 的元素。

第六步:nums1 = {1,2}

                按照第一步到第五步排序左侧数组。

第七步:nums2 = {5,8,9}

                按照第一步到第五步排序右侧数组。

最终得到排序好的数组: nums = {1,2,4,5,8,9}        

2.3.2 编码实现

    public static void fastSort1(int[] nums,int left,int right){
        if(left<right){
            int mark = sort1(nums,0,nums.length-1);
            fastSort(nums,left,mark-1);
            fastSort(nums,mark+1,right);
        }
    }
 
    public static int sort1(int[] nums,int left,int right){
        int leftIndex = left+1;
        int rightIndex = right;
        int mark = -1;
        int key = nums[left];
        while(leftIndex<rightIndex){
            while(nums[leftIndex]<key && leftIndex<rightIndex){
                leftIndex++;
            }
            while(nums[rightIndex]>key && leftIndex<rightIndex){
                rightIndex--;
            }
            if(left<right){
                int tmp = nums[leftIndex];
                nums[leftIndex] = nums[rightIndex];
                nums[rightIndex] = tmp;
            }
        }
        if(nums[leftIndex]<key){
            mark = leftIndex;
        } else {
            mark = leftIndex-1;
        }
        nums[left] = nums[mark];
        nums[mark] = key;
 
        return mark;
    }

2.3.3 时间复杂度和空间复杂度

        快速排是采用分治法进行遍历的,相当于遍历一个二叉树,理想的二叉树结构如下图所示:

这种情况二叉树的深度是3,根据完全二叉树的定义,深度计算公式 log(N+1),每一层需要比较N次,所以时间复杂度是 T(n) = O(N*logN)。因为是使用的递归,所以每一层递归都需要数组存储,理想情况下空间复杂度 S(n) = O(logN)。

        上面讲的是最理想的情况下,空间复杂度和时间复杂度,二叉树有可能并不是上面的样子,二叉树的深度有可能是N ,这种情况下 时间复杂度 T(n) = O(n^2) ,空间复杂度 S(n) = O(n)。

         快速排序的平均时间复杂度 T(n) = O(N*logN) ,空间复杂度 S(n) = O(NlogN) 。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值