快速排序(思想+实现)

快排基本思想:

采用二分的思想。每次从待排序的数组中选取一个元素作为基准,将所有小于基准的元素放到其左侧,大于基准的元素放到其右侧。这样整个数组成为一个局部有序的数组。然后再分别对左侧、右侧的数组进行快速排序,直到数组中元素个数小于等于1。

为什么快排的平均时间复杂度是O(nlogn),而冒泡、选择、插入排序都是O(n^2)?

对于冒泡/选择/插入:

每一趟排序,遍历n个元素,时间复杂度O(n),确认1个元素的位置。

确认n个元素的位置需要n趟排序。

对于快排(或者其他二分思想的排序)在平均情况下:

第1趟排序,遍历n个元素,时间复杂度O(n),确认1个元素的位置;

第2趟排序,遍历n个元素,时间复杂度O(n),确认2个元素的位置;

第3趟排序,遍历n个元素,时间复杂度O(n),确认4个元素的位置;

第4趟排序,遍历n个元素,时间复杂度O(n),确认8个元素的位置;

……

每次排序确认的元素个数呈2的指数倍增长,因此确认n个元素只需要logn趟排序

这也是为什么快速排序最坏情况会达到O(n^2),因为二分失效,导致每次只能确认一个元素。当然也有一些方法用于避免这种最坏情况(下次再补这部分的内容吧

具体实现:

每一趟选第一个元素作为基准。两个指针l和r分别指向开始元素和结尾元素。

  void quickSort(vector<int>&heights,int start,int end){
        if(end-start<=0) return;
        //
        int q=heights[start];    //基准元素
        int i=start,j=end;    //两个指针,i向右移动,j向左移动
        while(i<j){
            if(heights[i]>q){
                swap(heights[i],heights[j]);
                swap(names[i],names[j]);
                j--;
            }
            else{
                i++;
            }
        }

        //判断指针所指的值是否大于基准元素,这里i不会越界
        if(heights[i]>q)i--;
        swap(heights[i],heights[start]);

        //二分
        quickSort(heights,start,i-1,names);
        quickSort(heights,i+1,end,names);
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值