基本思想
通过一轮的排序将序列分割成独立的两部分,其中一个序列的关键字均比另一个序列中的关键字小。继续对长度较短的序列进行同样的分割,最后到达整体有序。在排序过程中,由于已经分开的两部分的元素不需要进行比较,故减少了比较次数,降低了排序时间。
关键字
“基准值”的选择有很多种方法。最简单的是使用第一个记录的关键字值。但是如果输入的数组是正序或者逆序的,就会将所有的记录分到“基准值”的一边。较好的方法是随机选取“基准值”,这样可以减少原始输入对排序造成的影响。但是随机选取“基准值”的开销大。
代码实现逻辑
为了实现一次划分,我们可以从数组(假定数据是存在数组中)的两端移动下标,必要时交换记录,直到数组两端的下标相遇为止。为此,我们附设两个指针(下角标)i 和 j, 通过 j 从当前序列的从右向左扫描,越过大于基准值的记录。当遇到小于基准值的记录时,扫描停止。通过 i 从当前序列从左向右扫描,越过小于基准值的记录。当遇到大于基准值的记录时,扫描停止。交换两个方向扫描停止的记录 a[j] 与 a[i]。 然后继续扫描,直至i与j相遇为止。扫描和交换的过程结束。此时i左边的记录的关键字值都小于基准值,右边的记录的关键字值都大于等于基准值。
缺点
快速排序方法在要排序的数据已经有序的情况下最不利于发挥其长处。
个人总结
下标i从左往右移动,下标j从右往左移动,为什么i和j循环主动移动呢?
假如数组A[]进行快速排序,A[0]=X作为比较值:
①当i=0时,即A[i]=A[0]=X时,j首先移动,j肯定会遇到比X小的值;
②此时A[i]与A[j]的值进行交换,此时A[j]=X,如果我再继续移动j,那么我在遇上比X小的值,那我该如何替换呢?
这就有点类似于int a= 1;int b= 10;交换a与b的值的时候必须有一个中间变量c类似,X就是中间值。
总结:任何时候,标准值会落在A[i]或者A[j]中的某一个,另外一个则负责移动。