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