快速排序算法

来源:互联网 发布:剑灵女咒术师捏脸数据 编辑:程序博客网 时间:2024/05/22 11:53


    前两天刷题,其中某些题需要用到排序,已经知道快速排序是个非常好的排序算法,感觉原理和实现过程也比较简单,就自己独立写代码去实现它。——“不要觉得简单就,想当然”

    不过糗事来了,快速排序的原理确实理解了,但编程时,很多细节没有注意,导致多次提交失败,要么死循环,要么编译出错,要么没有排好序……做一道题的时间严重超出了我预期的时间。但这次长时间的“试错”,让我再次重新认识了一下“快速排序算法”,真正的理解了它的实现细节。——“小心,你也不一定能顺利的独立的写出快速排序算法,如果你真的可以,那你是我的偶像”

    在这里,就分享一下自己写快速排序算法的代码和经验,以及其中需要注意的细节。——“希望对你有用”

    虽然STL当中的容器,很多都集成了排序算法,但某些特殊情况还是需要自己独立编写排序算法才能更高效的完成任务。



快速排序,使用递归的方式实现,快速排序算法递归的开始需要给出终止条件,那么这个终止条件是什么?因为快速排序的核心思想是用数组(子数组)中的第一个数作参照ref,将数组(子数组)分为“小于等于参照 ref ”的子数组和“大于等于参照 ref ”的子数组,然后继续重复上面的过程。而这个核心思想的关键是找到这个参照ref的位置k(这个位置k就是排完序之后该ref的位置),即当 i<k 时,arr[i]<=arr[k],当 i>k 时,arr[i]>=arr[k]。找到位置k后,将数组从这个位置k分割成两个子数组,而ref的这个位置k将不再变化,所以可以将快速排序的过程理解为,每次将数组(子数组)排序前的第一个位置的数据 ref 进行排序后的“归位 k”的过程。快速排序的返回结果一定是一个排好序的子数组(数组),经过位置k不断分割得到的两个子数组,再次进行递归过程中,长度会逐渐缩短,当子数组的长度为1的时候,说明该子数组是已经排好序的数组,所以直接返回,就不需要再进行排序了,即递归终止。所以终止条件是,当前子数组的长度为 1。


另外,三个需要注意的问题是:
1,需要先从左侧开始向右寻找,再从右侧开始向左寻找,是为了最后和右侧寻找的位置进行交换;
2,与ref的判断必须是“<=”和“>=”,跳过“
==ref”的位置,否则无法完成排序;
3,向寻找或向左寻找的边界条件需要注意,否则容易运行出错。


void quickSort(vector<int>& vin, int front, int tail) {if (front == tail) return;// 终止条件,当前子数组的长度为 1int lhs = front + 1, rhs = tail;while (vin[lhs] <= vin[front] && lhs < rhs) lhs++;// 先寻找 > vin[front]的位置,注意符号 <=,即跳过 ==vin[front]的情况,边界不超过右值while (vin[rhs] >= vin[front] && front < rhs) rhs--;// 先寻找 < vin[front]的位置,注意符号 >=,即跳过 ==vin[front]的情况,边界不超过 子数组中的第一个位置 frontwhile (lhs < rhs) {swap(vin[lhs], vin[rhs]);while (vin[lhs] <= vin[front] && lhs < rhs) lhs++;// 先寻找 >while (vin[rhs] >= vin[front] && front < rhs) rhs--;// 先寻找 <}// 注意必须是和 rhs(而不是lhs)判断,否则会出错(当front为当前子数组的最小值时会有排序错误),因为这个 rhs 就是“归位 k”位置// rhs 是倒数第一个 小于vin[front] 的数据的位置if (front != rhs)swap(vin[front], vin[rhs]);// 如果 front == rhs,说明 front位置 是“归位 k”位置,不用交换。否则交换if (front < rhs)quickSort(vin, front, rhs - 1);// 存在 小于等于参照 ref 的 新子数组,长度缩减if (rhs < tail)quickSort(vin, rhs + 1, tail);// 存在 大于等于参照 ref 的 新子数组,长度缩减return;}



    通过比较自己编写的快速排序算法,和调用系统的sort(nums.begin(),nums.end())算法,进行比较,发现使用自己编写的快速排序算法还是快一点的,这更加鼓励我靠自己去探索更优秀的代码,而不依赖系统所给的。




原创粉丝点击