排序算法之快速排序

快速排序:其根本思想是基于分治法的,每次从待排序的序列中找出一个数记为p,将序列中所有比p大的数字放在p后面,将所有比p小的数放在p前面,再对p左右两边的子序列执行上述操作,直到子序列的长度为1(一个数一定有序),最后返回的序列就是有序序列。


快排相关:

  • 空间复杂度:因为快排是基于递归的,所以需要一个递归栈来保存每层的调用信息,平均情况为O(logn),最差的情况下为O(n)
  • 时间复杂度:当原始序列基本有序或逆序时,时间复杂度为 O(N^2),正常情况下的时间复杂度为O(nlogn)

关于快排的实现方式我们可以这样理解:

  1. 得到一个p(通常直接取序列的第一个元素)
  2. 从序列的最后位置向前遍历,直到找到一个比p小的数,记下当前数的位置
  3. 从序列的最开始位置向后遍历,直到找到一个比p大的数,记下当前数的位置
  4. 将两个数交换位置
  5. 重复上述2,3,4步,直到p前面的数都小于p,p后面的数都大于p
  6. 对p的左右子序列分别进行上述2,3,4,5操作
  7. 最后得到有序序列

因为没有图片的缘故,只看文字可能不好理解,建议结合代码反复看一看
快排的第一种实现:


public static int  qsort(int a[], int l, int r) {
        int i=l, j=r;
        int x = a[i];

        //2,6,4,3,1,5
        while(i < j) {

            while(i < j && a[j] >= x) {
                j--;
            }

            if(i < j) {
                a[i] = a[j];
            }

            while(i < j && a[i] < x) {
                i++;
            }
            if(i < j) {
                a[j] = a[i];
            }
        }
        a[i] = x;
        return i;
    }

    public static void partition(int a[], int l, int r) {
        if(l < r) {
            int part = qsort(a, l, r);
            partition(a, l, part-1);
            partition(a, part+1, r);
        }
    }

我们可以看到qsort方法来执行一次对一个数左右子序列的处理,partition方法用于处理qosrt方法的子序列

快排也可以只用一个方法来递归完成:

public static void qsort2(int[] a, int l, int r) {
        if(l < r) {
            int i=l, j=r;
            int x = a[i];

            while(i < j) {
                while(i < j && a[j] >= x) {
                    j--;
                }
                a[i] = a[j];

                while(i < j && a[i] < x) {
                    i++;
                }
                a[j] = a[i];
            }
            a[i] = x;
            qsort2(a, l, i-1);
            qsort2(a, i+1, r);
        }
    }

测试代码:

public static void main(String[] args) {
        int a[] = new int[]{2,6,4,3,1,5};

        qsort2(a, 0, a.length-1);

        for(int i : a) {
            System.err.print(i + ",");
        }
    }

测试结果:

[1, 2, 3, 4, 5, 6]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值