快速排序 Java实现 (详细解释partition的过程)

排序思想

快速排序是交换排序的一种,在平均情况下的排序时间复杂度为O(nlogn),在最坏的情况下(数组已经有序的情况下),排序时间复杂度为O(n^2)

快排的思想是每趟排序确定一个基准值的位置,并使得该值左边的值都小于它,右边的值都大于它,再对左右两个子数组进行快排的递归调用,直至所有数字都放到了对应的位置上,排序结束。

所以快排中最重要的操作就是partition()方法的实现,(确定基准值的位置并使得该值左边的值都小于它,右边的值都大于它)

最常见的partition方法就是挖坑法

  1. 将待排序数组最左边的元素定义为基准值pivot,并设置两个指针(哨兵)low,high分别指向数组的最左边的元素与最右边的元素;
  2. 此时将pivot从数组中取出,nums[low]这个位置便空了出来,形成了一个坑,等待数据放入;
  3. 首先移动指针high,使其向左边移动(high–),每次移动之前先检查其指向的元素是否小于pivot基准值,如果不小于则移动,如果小于则将其放入指针low指向的坑里,此时指针high指向的位置空了出来,形成了一个新的坑,等待数据的插入;(仔细思考,这样做的目的就是为了让比pivot小的元素都放到pivot最终位置的左边);
  4. 接下来移动指针low,使其向右边移动(low++),与上述步骤相似,每次移动之前检查其指向的元素是否大于pivot,如果不大于则移动指针,如果大于则将其放入指针high指向的坑里,此时指针low指向的位置就又空了出来,形成一个坑;(同理,这个操作是为了将比pivot大的元素放到pivot最终位置的右边)
  5. 重复上述3、4步骤,直到指针low、high相遇
  6. 相遇之后指针low、high都指向同一个元素,并且该元素中一定没有存放数据,是一个坑,这个位置就是基准值pivot排序之后的最终位置,将pivot放入到这个坑里即可

这样,便完成了一次的partition操作,接下来只需对左右两个子数组递归调用快排即可

代码实现

在代码中我实现了两种不同的partition()方法,第一种是挖坑法,第二种有兴趣的话大家可以看一看,其实只是调整了交换元素操作的位置

    public void quickSort(int[] nums, int low, int high){
        if(low < high){
            int pivot = partition(nums, low, high);		//调用partition获得pivot最终的位置,
            									//并使得pivot左边的值都小于它,右边的值都大于它
            quickSort(nums, low, pivot-1);		//递归左边的子数组
            quickSort(nums, pivot+1, high);		//右边的子数组
        }
    }

    //挖坑法
    public int partition(int[] nums, int low, int high){
        int pivot = nums[low];
        while(low<high){
            while(low<high && nums[high]>=pivot)
                high--;
            nums[low] = nums[high];
            while(low<high && nums[low]<=pivot)
                low++;
            nums[high] = nums[low];
        }
        nums[low] = pivot;
        return low;
    }

    public int partition1(int[] nums, int low, int high){
        int k = low;
        int pivot = nums[low];
        while(low<high){
            while(low<high && nums[high]>=pivot)
                high--;
            while(low<high && nums[low]<=pivot)
                low++;
            swap(nums,low,high);
        }
        swap(nums,k,low);
        return low;
    }

    public void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值