快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
步骤为:
- 从数列中挑出一个元素,称为 "基准"(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
1 // 参考白话经典算法之快速排序的思想 2 #include <stdio.h> 3 4 // 起始点作为基准点 5 int Partition(int *a, int baseIndex, int nHigh) 6 { 7 if ((NULL == a) || (baseIndex < 0) || (baseIndex > nHigh)) 8 { 9 printf ("Invalid Parameter(s)!\n"); 10 return -1; 11 } 12 13 int nTemp = a[baseIndex]; 14 int i = baseIndex; 15 int j = nHigh; 16 17 while (i < j) 18 { 19 while ((i <j) && (a[j] > nTemp)) 20 { 21 --j; 22 } 23 24 if (i < j) 25 { 26 a[i++] = a[j]; 27 } 28 29 while ((i < j) && (a[i] <= nTemp)) 30 { 31 ++i; 32 } 33 34 if (i < j) 35 { 36 a[j--] = a[i]; 37 } 38 } 39 40 a[i] = nTemp; 41 42 return i; 43 } 44 45 void QuickSort(int *a, int nLow, int nHigh) 46 { 47 if ((NULL == a) || (nLow < 0)) 48 { 49 printf ("Invalid Parameter(s)!\n"); 50 return; 51 } 52 53 if (nLow < nHigh) 54 { 55 // 将数组分成两部分 56 int nDiv = Partition (a, nLow, nHigh); 57 58 if (-1 != nDiv) 59 { 60 // 递归左边 61 QuickSort (a, nLow, nDiv - 1); 62 63 // 递归右边 64 QuickSort (a, nDiv + 1, nHigh); 65 } 66 } 67 } 68 69 // 简化代码 70 void QuickSort1(int *a, int nLow, int nHigh) 71 { 72 if ((NULL == a) || (nLow < 0)) 73 { 74 printf ("Invalid Parameter(s)!\n"); 75 return; 76 } 77 78 if (nLow < nHigh) 79 { 80 int nTemp = a[nLow]; 81 int i = nLow; 82 int j = nHigh; 83 84 while (i < j) 85 { 86 while ((i <j) && (a[j] > nTemp)) 87 { 88 --j; 89 } 90 91 if (i < j) 92 { 93 a[i++] = a[j]; 94 } 95 96 while ((i < j) && (a[i] <= nTemp)) 97 { 98 ++i; 99 } 100 101 if (i < j) 102 { 103 a[j--] = a[i]; 104 } 105 } 106 107 a[i] = nTemp; 108 109 QuickSort1 (a, nLow, i - 1); 110 111 QuickSort1 (a, i + 1, nHigh); 112 } 113 } 114 115 int main(void) 116 { 117 int a1[9] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; 118 int a2[9] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; 119 120 QuickSort (a1, 0, 8); 121 122 QuickSort1 (a2, 0, 8); 123 124 for (int i = 0; i < 9; ++i) 125 { 126 printf ("%d ", a1[i]); 127 } 128 129 printf ("\n"); 130 131 for (int i = 0; i < 9; ++i) 132 { 133 printf ("%d ", a2[i]); 134 } 135 136 printf ("\n"); 137 138 return 0; 139 }