思路一:
第一种是根据算法导论上的思想:取数组的最后一个元素为主元,i初始化为最低位元素的前一个位置,j指向遍历数组中待排序的元素,当j所指元素比主元小的时候i= i + 1,然后交换i和j所指的元素,j不断遍历,遇到小于主元的就进行交换,这样就能一直维持这样一个序列,i之前的元素(包括i所指元素本身)都是比主元小的元素,i到j之间都是比主元大的元素,j(包括j所指元素)之后都是待排序的元素,最后交换主元和第一个比主元大的元素就可以完成划分。
算法导论具体介绍如下:
快速排序是基于分治模式处理的,对一个典型子数组A[p…r]排序的分治过程为三个步骤:
具体实现快速排序的伪代码:
具体例子分析详情:
C++代码实现如下:
1 | //1、进行区域的划分 |
思路二:
第二种是严蔚敏的数据结构(C语言版)上的思想:取数组的第一个元素为主元,左(left)、右(height)两指针进行遍历,先右边开始边查找比主元小的(比主元大时height直接减减),找到就直接覆盖左边所指的元素,然后从左边开始查找比主元大的元素,找到就直接覆盖右边所指的元素,依次循环进行。最后low不小于height时把所取的主元付给low所指的位置,完成划分。
数据结构(C语言版)具体介绍如下:
具体实现快速排序的伪代码:
具体例子分析详情:
C++代码实现如下:
1 | //1、进行区域的划分 |
最后呈上快速排序的非递归实现:
1 | void quickSortNonRecursive(vector<int> &nums, int low, int height) |
其实经过测试非递归的算法比递归实现还要慢。 因为递归算法使用的栈由程序自动产生,栈中包含:函数调用时的参数和函数中的局部变量。如果局部变量很多或者函数内部又调用了其他函数,则栈会很大。每次递归调用都要操作很大的栈,效率自然会下降。而对于非递归算法,每次循环使用自己预先创建的栈,因此不管程序复杂度如何,都不会影响程序效率。但是对于上面的快速排序,由于局部变量只有一个mid,栈很小,所以效率并不比非递归实现的低。
具体的关于快速排序的优化,见文章快速排序优化。