快速排序算法详解

快速排序算法

1.1 算法分析

快速排序是一种不稳定的,时间复杂度为O(nlogn)的排序算法.

基本思想:1.选定基准值key。

2.通过双指针不断地移动,将比key大的值移动到key的右边,比key小的值移动到key的左边,直到双指针相遇(即代表该过程已完成)

3.上述过程完成后,对于以原key区分形成的两个子数组,分别重复1和2操作。

4.直到所有的子过程完成后,我们就得到了最后的有序数组

快速排序采用了分治递归的思想,通过问题的分解,简化为子问题求解。

1.2算法描述
  • 在一个无序数组中,选定一个基准值(一般为第一个元素),设该值为Key。(升序)
  • 使用low和high分别指向数组的第一个以及最后一个元素,为保留数据,我们使用i,j两个变量来存储low与high的值。
  • 我们从数组的尾指针(j)开始,通过移动j,来寻找比key小的元素,也就是我们常用的while循环,要注意的是,如果与前方指针i相遇,则说明过程已经完成,此时也应该结束寻找,否则将会出现越出。
  • 在寻找到比key小的元素后,我们将该元素放在i(初始情况下指向key)位置,并且让i指向下一个位置。
  • 此时我们再从数组的头指针(i)开始,从前往后地寻找比key大的元素,过程同前文第二点类似,并在寻找到该元素后,将该元素放在j位置,并且使得j往前移动一位。
  • 不断重复第2,3,4部,直到两指针i和j相遇,则相遇的位置,就是我们基准值所在的位置,这时,我们将key赋值到该位置,则此部分完成
  • 这时候我们得到了以low到i-1与i+1到high两个新的子数组,于是我们递归调用自身,进行同样的操作,直到最后结果完成。
  • 注意:递归收拢条件是low始终小于high。
1.3 思路分析

接下来我们来模拟这一算法思路:
假设有数组:

78 21 98 55 64 33 82

则在第一步,我们以78作为基准值,数据变化如下:

key:78 从后往前,33比78小,得到:

(33) 21 98 55 64 ? 82

从前往后,98比78大

(33) 21 ? 55 64 (98) 82

之后:

(33) 21 (64) 55 ? (98) 82

则此时我们得到:

(33) 21 (64) 55 78 (98) 82

则有33 21 64 55与98 82为子数组

对于33 21 64 55:

? 21 64 55=>21 ? 64 55

得到新的子数组:21与64 55

则有数组:21 33 55 64

另外一部分同理,则得到最后结果:

21 33 55 64 78 82 98

2.1代码:
void quickSort(int arrs[], int low, int high)
{
    //递归出口:
    if (low < high)
    {
        //通过i,j存储low与high,并以第一个数据作为基准值key
        int i = low;
        int j = high;
        int key = arrs[low];
        //每一次操作都是以i,j是否相遇作为结束条件,相遇则代表两边都已经完成操作
        while (i < j)
        {
            //从后往前扫描,若是遇到了比key小的,则循环会退出,并且当前j会指向该元素的位置
            while (i < j && arrs[j] >= key)
                j--;
            //将找到的元素放到i指向的位置,并让i指向下一个位置
            if (i < j)
                arrs[i++] = arrs[j];
            //重复与上面类似的操作
            while (i < j && arrs[i] < key)
            {
                i++;
            }
            if (i < j)
            {
                arrs[j--] = arrs[i];
            }
        }
        //这是指针已经相遇,则此位置即为key所在的位置
        arrs[i] = key;
        //我们得到的新数组,其位置下标就是[low,i-1]与[i+1,high],进行递归调用
        quickSort(arrs, low, i - 1);
        quickSort(arrs, i + 1, high);
    }
}

2.2总结:

快速排序的代码比较符合正常逻辑,虽然是递归调用,但是仍然比较容易理解,分治递归求解子问题

快速排序的主要特点:比较脆弱,内循环比较短小,实际中性能较优越,只需要使用一个很小的辅助栈。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值