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所示。 |