排序算法-快排

    今天聊聊排序算法,排序算法平时也会用到,有很多比如,冒泡,快排,选择,归并排序等.今天就聊一聊快速排序算法排序算法的一个宗旨就是经过一趟排序,何为一趟排序呢?就是遍历完一次数组,数组中的一部分数据比另外一部分的数据都要小.当然这两部分数据内部仍然是无序的,然后我们再对这两部分数据分别进行排序,如此递归下去.所以整个算法的核心思想就是这样,今天介绍两种实现快速排序的方法,一种是交换排序以及另一种方法(这种我也叫不出来方法),大家看代码就能看明白.

    首先看第一种方法,

void quickSort1(vector<int> &nums, int left, int right){
    if (left<right){
        int key = nums[left], low = left+1, high = right;
        while (low<=high){   //为什么是<=
            while (low<high && nums[low]>key && nums[high]<key)
                swap(nums[low++], nums[high--]);
            if (nums[low]<=key) low++;
            if (nums[high]>=key) high--;
        }
        swap(nums[left], nums[high]); //为什么是和high位置交换
        quickSort1(nums, left, high-1);
        quickSort1(nums, high+1, right);
    }
}
    因为算法是从两个端点向中间收缩,所以我们要确保left<right,首先我们选取一个key值,等完成一趟排序之后,key左边的元素统统小于key右边的元素,然后再从key处割裂开,左右两边分别进行以上算法.然后定义low为左边的起始点,high为右边的起始点.如果满足第一个while条件,就相当于左边的数值大,右边的数值小,然后我们交换一下两者,同时把low和high接着往中间走一步,再继续比较.当不符合条件时,我们跳出当前while循环,然后执行下面两个判断,这两个判断的目的是为了防止产生死循环,如果没有这两句话,当nums[low]=key或者当nums[high]==key时,不符合上面的while循环,是不是就陷入了死循环.当退出while循环时,high<=low而且nums[low]>key,而且这一个过程中key值一直没动,我们需要把他放在合适的位置,此时nums[low]>key,那key还能和low位置的值交换吗?好像不可以了,那为什么和high位置的值交换呢,如果我们在第一个循环中设置low<high,那么high的最小值就是low,所以也不能和high位置的值交换,那如果我们设置为low<=high时,结束while循环时high位置就在low-1处,所以key和这个位置的值交换.这样就完成了一趟遍历,接下来,就从high处把数组割裂开,然后对两段数组分别排序即可.

    第二种方法:代码如下

void quickSort2(vector<int> &v, int left, int right){
    if (left < right){
        int key = v[left], low = left, high = right;
        while (low < high){
            while (low < high && v[high] >= key)
                high--;
            if (low < high)
                v[low++] = v[high];
            while (low < high && v[low] <= key)
                low++;
            if (low < high)
                v[high--] = v[low];
        }
        v[low] = key;
        quickSort2(v, left, low-1);
        quickSort2(v, low+1, right);
    }
}
        这种方法就比较好理解了,先从右边遍历数组,直到遇到一个比key值小的,然后把这个值放到low位置处,low指向下一个位置,这时数组中有两个v[high]了,在low位置处(前面)的这个是正确的位置,在high处这个位置是不正确的位置.然后从左边开始向右遍历,直到遇到一个比key值大的数值,然后把他放到右边的high位置处,这时是不是数组中有了两个v[low]了,前面这个位置是不正确的,所以要把key值放到这个位置.接着从low处割裂开,然后对两段数组进行排序.


猜你喜欢

转载自blog.csdn.net/qq_18293213/article/details/79052144