10.3.2 快速排序

  起泡排序是通过一趟"起泡"选定关键字最大的记录,所有剩余关键字均小于它的记录继续进行排序,快速排序则是通过一趟排序选定一个关键字介于"中间"的记录,从而使剩余记录可以分成两个子序列分别继续排序,通常称该记录为"枢轴"。如右图所示,假设一趟快速排序之后枢轴记录的位置为 i,则得到的无序记录子序列(1) R[s..i-1] 中记录的关键字均小于枢轴记录的关键字,反之,得到的无序记录子序列(2)R[i+1..t] 中记录的关键字均大于枢轴记录的关键字,由此这两个子序列可分别独立进行快速排序。

例题例如,关键字序列    ( 52, 49, 80, 36, 14, 75, 58, 97, 23, 61 )
   经第1趟快速排序之后为 ( 23, 49, 14, 36) 52 (75, 58, 97, 80, 61 )
   经第2趟快速排序之后为 ( 14) 23 (49, 36) 52 (61, 58) 75 (80, 97 )
   经第3趟快速排序之后为 ( 14, 23, 36, 49, 52, 58, 61, 75, 80, 97 )

  快速排序的算法如下:

算法 算法 10.9
  void QSort (RcdType R[], int s, int t )
 {
  // 对记录序列 R[s..t] 进行快速排序
  if (s < t) {        // 长度大于1
   pivotloc = Partition(R, s, t);
                // 对 R[s..t] 进行一趟快排,并返回枢轴位置
   QSort(R, s, pivotloc-1); // 对低子序列递归进行排序
   QSort(R, pivotloc+1, t); // 对高子序列递归进行排序
  } // if
 } // Qsort

算法 算法 10.10
  void QuickSort( SqList & L)
 {
  // 对顺序表 L 进行快速排序
  QSort(L.r, 1, L.length);
 } // QuickSort
 
  

  快速排序的算法是一个递归函数,因此算法10.9中必须引入一对参数 s 和 t 作为待排序区域的上下界。在算法的递归调用过程执行中,这两个参数随着 "区域的划分"而不断变化。对顺序表L进行快速排序调用算法10.9时,s 和 t 的初值应分别置为1和 L.length 。如算法10.10所示。