快速排序(Quick Sort)的C++实现 1. 算法简介 快速排序是一种基于 分治法 的高效排序算法。通过选择一个“基准”(pivot),快速排序将序列分成两个子序列,分别递归地进行排序。在平均情况下,时间复杂度为 ( O(n \log n) ),且具有较小的常数因子,在实际中通常比其他排序算法更快。
2. 算法步骤 选择基准值(Pivot) : 通常选择序列中的第一个元素或中间元素作为基准值。分区(Partitioning) : 将序列中的元素按照基准值划分成两部分:左侧部分小于基准值,右侧部分大于基准值。递归调用 : 对左侧和右侧的子序列分别进行快速排序。结束条件 : 当子序列的长度为1或0时,不再递归。3. 代码实现 标准的递归实现: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream> #include <vector> void swap (int & a, int & b) { int temp = a; a = b; b = temp; } int partition (std::vector<int >& arr, int low, int high) { int pivot = arr[low]; while (low < high) { while (low < high && arr[high] >= pivot) { --high; } arr[low] = arr[high]; while (low < high && arr[low] <= pivot) { ++low; } arr[high] = arr[low]; } arr[low] = pivot; return low; } void quickSort (std::vector<int >& arr, int low, int high) { if (low < high) { int pivotIndex = partition (arr, low, high); quickSort (arr, low, pivotIndex - 1 ); quickSort (arr, pivotIndex + 1 , high); } } int main () { std::vector<int > arr = {29 , 10 , 14 , 37 , 13 }; quickSort (arr, 0 , arr.size () - 1 ); std::cout << "排序结果: " ; for (int num : arr) { std::cout << num << " " ; } return 0 ; }
4. 细节分析 选择基准值 : 代码中选择了第一个元素作为基准值 pivot,在某些情况下(如已排序的数组)会导致最坏的时间复杂度 ( O(n^2) )。通过随机选择基准值或选择中间元素,可以提高算法在特定输入下的效率。
分区过程 :
从右向左找第一个小于基准值的元素,放在左侧; 从左向右找第一个大于基准值的元素,放在右侧; 这个过程不断交替进行,直到左右两侧交叉,最后将基准值归位。 递归调用 : 快速排序通过递归实现对左右两个子序列的排序。由于每次递归调用的数组长度缩小,因此在平均情况下递归深度为 ( \log n )。
时间复杂度 :
最优时间复杂度 : 当每次划分都非常均匀时,递归深度为 ( \log n ),每次分区的代价为 ( O(n) ),因此时间复杂度为 ( O(n \log n) )。最坏时间复杂度 : 当数组已经有序或接近有序时,每次划分都导致极端不平衡的分区,递归深度为 ( O(n) ),时间复杂度为 ( O(n^2) )。空间复杂度 : 快速排序是 原地排序 算法,因此空间复杂度仅为递归调用时的栈空间,最优情况下为 ( O(\log n) ),最坏情况下为 ( O(n) )。
5. 迭代实现 使用递归容易导致栈溢出问题,在此基础上可以使用栈手动模拟递归过程,进行迭代实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream> #include <vector> #include <stack> struct Range { int start, end; Range (int s, int e) : start (s), end (e) {} }; int partition (std::vector<int >& arr, int low, int high) { int pivot = arr[low]; while (low < high) { while (low < high && arr[high] >= pivot) --high; arr[low] = arr[high]; while (low < high && arr[low] <= pivot) ++low; arr[high] = arr[low]; } arr[low] = pivot; return low; } void quickSortIterative (std::vector<int >& arr) { std::stack<Range> stack; stack.push (Range (0 , arr.size () - 1 )); while (!stack.empty ()) { Range range = stack.top (); stack.pop (); if (range.start < range.end) { int pivot = partition (arr, range.start, range.end); stack.push (Range (range.start, pivot - 1 )); stack.push (Range (pivot + 1 , range.end)); } } } int main () { std::vector<int > arr = {29 , 10 , 14 , 37 , 13 }; quickSortIterative (arr); std::cout << "排序结果: " ; for (int num : arr) { std::cout << num << " " ; } return 0 ; }