• 快速排序、归并排序、堆排序的C++实现_独家原创


    作为最常用的三大排序方法,必须掌握。这里给出递归写法C++实现,相比迭代写法会更容易理解。

    代码实现

    1. #include
    2. #include
    3. using namespace std;
    4. class Solution {
    5. public:
    6. void SortArr(vector<int>& nums) {
    7. //quickSort(nums, 0, nums.size() - 1);
    8. //mergeSort(nums, 0, nums.size() - 1);
    9. heapSort(nums);
    10. }
    11. private:
    12. void quickSort(vector<int>& nums, int l, int r) {
    13. if (l < r) {
    14. int pos = partition2(nums, l, r);
    15. quickSort(nums, l, pos - 1);
    16. quickSort(nums, pos + 1, r);
    17. }
    18. }
    19. // 以pivot分隔,选最左为pivot
    20. // 第一种Partition方式,对撞指针法
    21. int partition(vector<int>& nums, int l, int r) {
    22. // 随机化加速,抑制最坏时间复杂度
    23. int i = rand() % (r - l + 1) + l;
    24. swap(nums[i], nums[l]);
    25. int pivot = nums[l];
    26. while (l < r) {
    27. // 右侧第一个小于pivot的元素
    28. while (l < r && nums[r] >= pivot) --r;
    29. nums[l] = nums[r];
    30. // 左侧第一个大于pivot的元素
    31. while (l < r && nums[l] <= pivot) ++l;
    32. nums[r] = nums[l];
    33. }
    34. nums[l] = pivot;
    35. return l;
    36. }
    37. // 第二种Partition方式,快慢指针法
    38. int partition2(vector<int>& nums, int l, int r) {
    39. // 随机化加速,抑制最坏时间复杂度
    40. int tmp = rand() % (r - l + 1) + l;
    41. swap(nums[tmp], nums[l]);
    42. int pivot = nums[l];
    43. int i = l + 1;
    44. for (int j = l + 1; j <= r; ++j) {
    45. if (nums[j] <= pivot) {
    46. swap(nums[i], nums[j]);
    47. ++i;
    48. }
    49. }
    50. swap(nums[i-1], nums[l]);
    51. return i-1;
    52. }
    53. void mergeSort(vector<int>& nums, int l, int r) {
    54. if (l == r) return;
    55. // 分解
    56. int mid = l + (r - l) / 2;
    57. mergeSort(nums, l, mid);
    58. mergeSort(nums, mid + 1, r);
    59. // 合并
    60. int i = l, j = mid + 1, pos = 0;
    61. vector<int> tmp(r - l + 1); // 合并时需要辅助数组
    62. while (i <= mid && j <= r) {
    63. tmp[pos++] = nums[i] <= nums[j] ? nums[i++] : nums[j++];
    64. }
    65. // 还有剩余
    66. while (i <= mid) {
    67. tmp[pos++] = nums[i++];
    68. }
    69. while (j <= r) {
    70. tmp[pos++] = nums[j++];
    71. }
    72. copy(tmp.begin(), tmp.end(), nums.begin() + l);
    73. }
    74. void heapSort(vector<int>& vec) {
    75. int sz = vec.size();
    76. // S1.建大顶堆
    77. // sz/2-1是最后一个非叶子节点
    78. for (int i = sz / 2 - 1; i >= 0; --i) {
    79. down(vec, i, sz);
    80. }
    81. // S2.大顶堆一个一个把最大的移到末尾
    82. for (int i = sz - 1; i > 0; --i) {
    83. swap(vec[0], vec[i]); // 把最大的移到末尾
    84. down(vec, 0, i); // 维持大顶堆,只需调整i=0,注意sz变为了i
    85. }
    86. }
    87. void down(vector<int> &vec, int i, int sz) {
    88. // 核心就是找i和其lSon、rSon三者最大的换到i的位置
    89. int lSon = i * 2 + 1;
    90. int rSon = i * 2 + 2;
    91. int maxIdx = i;
    92. if (lSon < sz && vec[lSon] > vec[maxIdx]) maxIdx = lSon;
    93. if (rSon < sz && vec[rSon] > vec[maxIdx]) maxIdx = rSon;
    94. if (maxIdx != i) {
    95. swap(vec[i], vec[maxIdx]);
    96. down(vec, maxIdx, sz);
    97. }
    98. }
    99. };
    100. int main() {
    101. Solution sln = Solution();
    102. vector<int> nums = { 1, 3, 5, 2, 2, 6 };
    103. sln.SortArr(nums);
    104. for (int num : nums) {
    105. cout << num << ' ';
    106. }
    107. return 0;
    108. }

    快排本身有劣势,数字一样变n方。

    实现思路可参考:

    算法 | 菜鸟分类 | 菜鸟教程 (runoob.com)

    漫画:“排序算法” 大总结 - 知乎 (zhihu.com)

  • 相关阅读:
    Flutter课程分享 -(系统课程 基础 -> 进阶 -> 实战 仿京东商城)
    外国固定资产管理系统功能有哪些
    92. 递归实现指数型枚举
    WinXP内核驱动调试
    Elasticsearch
    springboot就业信息管理系统springboot32
    自动驾驶公交车第 1 部分:车辆运营技术要求
    2022.11.5 英语背诵
    6.3 字符数组
    英文网页批量翻译导出本地教程
  • 原文地址:https://blog.csdn.net/weixin_36389889/article/details/126675854