【排序】快速排序

原理

对于一个数组x,快速排序流程如下:

  1. 确定分界点a,可以取x[l]、x[r]、x[l + r / 2]、随机(四种都可以)
  2. 调整区间,使得:区间被分成 <= a 和 >= a的两部分,左边 <= a,右边 >= a(注意,a不一定在原来的位置了)
  3. 递归处理左右两边

重点在于第二步调整区间上。

在这里插入图片描述

做法是:在区间[l, r]中,指定两个指针i、j。

  • 当i指向的数 < a的时候,i往右移动
  • 当j指向的数 > a的时候,j往左移动

当i和j停下来的时候,说明x[i] >= ax[j] <= a,则x[i] >= x[j]。那根据我们的想要实现的目的,要保证左边 <= a,右边 >= a,也就是x[i] <= x[j]。因此,需要将x[i]与x[j]交换。

复杂度

代码

import java.util.*;
import java.io.*;

class Main {
    
    public static void quick(int[] x, int l, int r) {
        if (l >= r) return ;
        
        int a = x[l + r >> 1], i = l - 1, j = r + 1;
        while (i < j) {
        	/**
				内层的循环不能加  i < j
				原因:如果加了i < j,那么两个do while之后,i = j。
				此时,如果x[j] > a,而后续的递归就会出问题,因为要保证[l, j]的数都 < a

				所以原则就是,最后外层循环退出的时候,要保证i > j,不能i = j
			*/
            do i ++ ; while (x[i] < a);
            do j -- ; while (x[j] > a);
            if (i < j) {
                int t = x[i];
                x[i] = x[j];
                x[j] = t;
            }
        }
        quick(x, l, j);
        quick(x, j + 1, r);
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] x = new int[n];
        
        for(int i = 0; i < n; i ++ ) x[i] = sc.nextInt();
        
        quick(x, 0, n - 1);
        
        for(int i = 0; i < n; i ++ ) System.out.print(x[i] + " ");
    }
}
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值