算法讲解-快速排序

快速排序涉及到一种常见的编程方法-递归

递归简单来说就是分而治之,找到重复的子问题。初学算法对递归可能比较难理解,建议多动手将
人脑递归逐渐减少。递归的出现本身就是简化思维的,但这种调用方式也增加了bug的概率。

排序数组

一个最短的有序数组是怎样的?【】 and 【n】 and 【n,k】当这个数组的长度小于2的时候
那么这个数组就可以称之为有序。
这也是递归的基条件。

举一个简单的递归例子,数组求和。我们可以轻松地使用循环解决这个问题,并且性能更高。那为什么不呢? 因为循环会增加思考的难度。。这时候大家肯定会想?你在逗我吧。老子递归的一脸懵逼。实际上递归是一种新的思维,就好比英语比汉语好学这是世界公认的但开始接受的过程总是困难的,要从心里认可它
数组求和的过程中我们反复操作的就是相加相邻的两个数,这就可以看做是一个子问题。

快速排序

	下面开始认识快速排序,根据上面的思想。排序数组的基条件就是数组的长度小于等于2。
	就想只关注相邻两个数那样,我们分解数组减小数组规模进而不断地缩小问题规模。

那么如何减小数组规模呢?
快速排序给出了一个方法,将数组中的一个数字作为一个基准然后将大于这个基准的数组放到一个数组里, 小于这个基准的放到另一个数组里这个动作一般称为partion

代码示例java
public class 快速排序{
    public  void quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        quickSort(arr, 0, arr.length - 1);
    }

    public  void quickSort(int[] arr, int l, int r) {
        if (l < r) {
            swap(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] p = partition(arr, l, r);
            quickSort(arr, l, p[0] - 1);
            quickSort(arr, p[1] + 1, r);
        }
    }

//    这是一个处理arr[l..r]的函数
//    默认以arr[r]做划分,arr[r] -> p <p ==p >p
//    返回等于区域(左边界,右边界)所以返回一个长度为2的数组
    public  int[] partition(int[] arr, int l, int r) {
        int less = l - 1;
//        小于等于 区域 的右边界
        int more = r;
//        大于等于区域的左边界
        while (l < more) {
            if (arr[l] < arr[r]) {
                swap(arr, ++less, l++);
//                小于区域右扩
            } else if (arr[l] > arr[r]) {
                swap(arr, --more, l);
//                大于区域做扩 i 不变
            } else {
                l++;
            }
        }
        swap(arr, more, r);
        return new int[] { less + 1, more };
    }

    public  void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

}

大家对于 这个partion过程用java实现理解有些困难,我简单的介绍一下实现思路
首先我在quickSort有定义了一个qucikSort辅助函数用于排序left ~ ritght。过程本身很清晰
1定义标准为最后一个数字 但是为了防止出现最差的情况也就是数组本身为正序转为倒序这样就会导致出现o(n^2)的概率为了避免这种情况 我们随机选取一个数字与最后一个数字交换这就从数学期望的角度(可以理解为平均概率)就是一个0(nlogn)的算法
2分区也就是partition操作为了优化我们采用交换的方式而不是再去构建两个数组
首先定义了两个左右边参考下图的两个边界从头开始遍历这个数组过程参照下图的解释用得到的边界递归下去直到数组的长度为1

初学的话建议python入手 更容易理解算法的思想。

分区逻辑

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值