当前位置:   article > 正文

9种排序算法对比_排序算法比较

排序算法比较

目录

本文里所有代码均为本人原创,若有错误请指正!!!

目录

  • 前言
  • 一、插入排序
    • 1.直接插入
    • 2.折半插入
    • 3.希尔排序
  • 二、选择排序
    • 1.直接选择
    • 2.树形选择
  • 三、交换排序
    • 1.冒泡排序
    • 2.快速排序
  • 四、其他排序
    • 1.归并排序
    • 2.基数排序
  • 总结


前言

        本人目前为大二学生,算法基础相对薄弱,写此blog来加强自己的算法能力,为ACM等竞赛打好基础。此blog可能有许多错误,还望各位大佬指正!若有志同道合的朋友,可以一起学习算法,共同进步!


提示:以下代码仅供参考!!!

一、插入排序

        插入排序,顾名思义,就是在待排序的数组中间插入元素,最终实现排序数组的效果。

1.直接插入

        直接插入是最基础的排序方法,其原理为:我们认为前面k个数组是已经排序好的状态,数组中的第k+1个元素,和前面k个元素进行比较,找到他要插入的位置,将后面的元素依次往后移即可。时间复杂度为O(n^2)。(为了方便对比数组大小均为100000(10^5),并且于直接插入算法进行比较)。

具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <algorithm>
  5. using namespace std;
  6. void Print(int* a, int n);
  7. void direct_sort(int* a, int n);
  8. void direct_sort(int* a, int n)
  9. {
  10. if (n <= 1)
  11. {
  12. cout << "Array Error!" << endl;
  13. }
  14. for (int i = 1; i < n; i++)
  15. {
  16. int k = 0;
  17. while (a[i] > a[k])k++;
  18. int temp = a[i];
  19. for (int j = i; j > k; j--)
  20. {
  21. a[j] = a[j - 1];
  22. }
  23. a[k] = temp;
  24. }
  25. }
  26. void Print(int* a, int n)
  27. {
  28. for (int i = 0; i < n; i++)
  29. {
  30. cout << a[i] << " ";
  31. }
  32. cout << endl;
  33. }
  34. int main()
  35. {
  36. srand((unsigned)time(NULL));
  37. int n;
  38. cout << "请输入待排序的数组大小:";
  39. cin >> n;
  40. int* num = new int[n];
  41. int* num1 = new int[n];
  42. for (int i = 0; i < n; i++)
  43. {
  44. num[i] = rand();
  45. num1[i] = num[i];
  46. }
  47. clock_t start = clock();
  48. direct_sort(num, n);
  49. clock_t end = clock();
  50. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  51. sort(num1, num1 + n);
  52. bool equal = true;
  53. for (int i = 0; i < n; i++)
  54. {
  55. if (num[i] != num1[i])
  56. {
  57. equal = false;
  58. break;
  59. }
  60. }
  61. if (equal)cout << "Right!" << endl;
  62. else cout << "Error!" << endl;
  63. delete[]num;
  64. delete[]num1;
  65. return 0;
  66. }

        排序数组大小为100000是数组(10^5)共用时5727ms。经验证结果正确。

 2.折半插入

       折半插入就是在直接插入算法的基础上的一个升级,其实我们并不需要去遍历前面的k个元素进行比较,我们只需要和前面数组大小为k的数组的中间值进行比较即可。如果这个数比中间值大,那么就把区间放到都半部分去继续进行比较;否则就在半部分进行比较。最后一定会找到插入的位置,这个查找的时间复杂度就降低到了O(logn)。找到位置后,在继续插入即可。这样这个算法的时间复杂度就是O(nlogn)。

       具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <omp.h>
  4. #include <stdlib.h>
  5. #include <algorithm>
  6. using namespace std;
  7. void Binary_Sort(int* a, int n);
  8. void Print(int* a, int n);
  9. int find_insert_point(int* a, int n, int l, int r, int i);
  10. void direct_sort(int* a, int n);
  11. void direct_sort(int* a, int n)
  12. {
  13. if (n <= 1)
  14. {
  15. cout << "Array Error!" << endl;
  16. }
  17. for (int i = 1; i < n; i++)
  18. {
  19. int k = 0;
  20. while (a[i] > a[k])k++;
  21. int temp = a[i];
  22. for (int j = i; j > k; j--)
  23. {
  24. a[j] = a[j - 1];
  25. }
  26. a[k] = temp;
  27. }
  28. }
  29. int find_insert_point(int* a, int n, int l, int r, int i)
  30. {
  31. if (l > r)return l;
  32. int m = (l + r) / 2;
  33. if (a[i] < a[m])return find_insert_point(a, n, l, m - 1, i);
  34. else return find_insert_point(a, n, m + 1, r, i);
  35. }
  36. void Binary_Sort(int* a, int n)
  37. {
  38. for (int i = 1; i < n; i++)
  39. {
  40. int p = find_insert_point(a, n, 0, i - 1, i);
  41. int temp = a[i];
  42. for (int j = i; j > p; j--)
  43. {
  44. a[j] = a[j - 1];
  45. }
  46. a[p] = temp;
  47. }
  48. }
  49. void Print(int* a, int n)
  50. {
  51. for (int i = 0; i < n; i++)
  52. {
  53. cout << a[i] << " ";
  54. }
  55. cout << endl;
  56. }
  57. int main()
  58. {
  59. srand((unsigned)time(NULL));
  60. cout << "请输入待排序的数组大小:";
  61. int n;
  62. cin >> n;
  63. int* num = new int[n];
  64. int* num1 = new int[n];
  65. for (int i = 0; i < n; i++)
  66. {
  67. num[i] = rand();
  68. num1[i] = num[i];
  69. }
  70. clock_t start = clock();
  71. Binary_Sort(num, n);
  72. clock_t end = clock();
  73. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  74. //Print(num, n);
  75. clock_t start1 = clock();
  76. direct_sort(num1, n);
  77. clock_t end1 = clock();
  78. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  79. bool equal = true;
  80. for (int i = 0; i < n; i++)
  81. {
  82. if (num[i] != num1[i])
  83. {
  84. equal = false;
  85. break;
  86. }
  87. }
  88. if (equal)cout << "Right!" << endl;
  89. else cout << "Error!" << endl;
  90. delete[]num;
  91. delete[]num1;
  92. return 0;
  93. }

        该算法排序数组大小为100000的数组需要2845ms。经验证结果正确。 

           时间上有问题,代码不知道哪里有问题,还望大佬指出!!!

3.希尔排序

        希尔排序的原理为:将数组中间隔gap的元素分为一组,并将组内进行排序,然后逐步减小gap,当gap为1时,数组就已经排序好了。这里我们选择的是让gap/=2,来逐步减小gap,这样这个算法的时间复杂度就是O(nlogn^2)或者是O(n^1.3)了。

具体代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. using namespace std;
  7. void Shell_Sort(int* a, int n);
  8. void Print(int* a, int n);
  9. void Swap(int& a, int& b);
  10. void direct_sort(int* a, int n);
  11. void direct_sort(int* a, int n)
  12. {
  13. if (n <= 1)
  14. {
  15. cout << "Array Error!" << endl;
  16. }
  17. for (int i = 1; i < n; i++)
  18. {
  19. int k = 0;
  20. while (a[i] > a[k])k++;
  21. int temp = a[i];
  22. for (int j = i; j > k; j--)
  23. {
  24. a[j] = a[j - 1];
  25. }
  26. a[k] = temp;
  27. }
  28. }
  29. void Swap(int& a, int& b)
  30. {
  31. int temp = a;
  32. a = b;
  33. b = temp;
  34. }
  35. void Shell_Sort(int* a, int n)
  36. {
  37. //Print(a, n,n);
  38. for (int gap = n/2; gap >= 1; gap >>= 1)
  39. {
  40. for (int i = gap; i < n; i++)
  41. {
  42. int temp = a[i];
  43. for (int j = i - gap; j >= 0; j -= gap)
  44. {
  45. if (temp < a[j])Swap(a[j + gap], a[j]);
  46. else break;
  47. }
  48. }
  49. }
  50. }
  51. void Print(int* a, int n)
  52. {
  53. for (int i = 0; i < n; i++)
  54. {
  55. printf("%d ",a[i]);
  56. //if ((i+1) % gap == 0)cout << endl;
  57. }
  58. cout << endl;
  59. }
  60. int main()
  61. {
  62. srand((unsigned)time(NULL));
  63. int n;
  64. cout << "请输入待排序的数组的大小:";
  65. cin >> n;
  66. int* num = new int[n];
  67. int* num1 = new int[n];
  68. for (int i = 0; i < n; i++)
  69. {
  70. num[i] = rand();
  71. num1[i] = num[i];
  72. }
  73. clock_t start = clock();
  74. Shell_Sort(num, n);
  75. clock_t end = clock();
  76. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  77. //Print(num, n);
  78. clock_t start1 = clock();
  79. direct_sort(num1, n);
  80. clock_t end1 = clock();
  81. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  82. bool equal = true;
  83. for (int i = 0; i < n; i++)
  84. {
  85. if (num[i] != num1[i])
  86. {
  87. equal = false;
  88. break;
  89. }
  90. }
  91. if (equal)cout << "Right!" << endl;
  92. else cout << "Error!" << endl;
  93. delete[]num;
  94. delete[]num1;
  95. return 0;
  96. }

         该算法排序数组大小为100000的数组仅需要28ms。经验证结果正确。 

 

二、选择排序

        选择排序,就是每次都选出这个数组中最大或者最小的元素,这样就可以将数组排序好了。

1.直接选择

        直接排序是最直接的排序方式,循环n次,每次都选出数组中第k小的数据,并把它放在数组的第k个位置。时间复杂度为O(n^2)。

具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. using namespace std;
  7. void Choose_Sort(int* a, int n);
  8. void Print(int* a, int n);
  9. void Swap(int& a, int& b);
  10. void direct_sort(int* a, int n);
  11. void direct_sort(int* a, int n)
  12. {
  13. if (n <= 1)
  14. {
  15. cout << "Array Error!" << endl;
  16. }
  17. for (int i = 1; i < n; i++)
  18. {
  19. int k = 0;
  20. while (a[i] > a[k])k++;
  21. int temp = a[i];
  22. for (int j = i; j > k; j--)
  23. {
  24. a[j] = a[j - 1];
  25. }
  26. a[k] = temp;
  27. }
  28. }
  29. void Swap(int& a, int& b)
  30. {
  31. int temp = a;
  32. a = b;
  33. b = temp;
  34. }
  35. void Print(int* a, int n)
  36. {
  37. for (int i = 0; i < n; i++)
  38. {
  39. printf("%d ", a[i]);
  40. //if ((i+1) % gap == 0)cout << endl;
  41. }
  42. cout << endl;
  43. }
  44. void Choose_Sort(int* a, int n)
  45. {
  46. for (int i = 0; i < n; i++)
  47. {
  48. int m = a[i];
  49. int dex = i;
  50. for (int j = i + 1; j < n; j++)
  51. {
  52. if (a[j] < m)
  53. {
  54. m = a[j];
  55. dex = j;
  56. }
  57. }
  58. Swap(a[i], a[dex]);
  59. }
  60. }
  61. int main()
  62. {
  63. srand((unsigned)time(NULL));
  64. cout << "请输入待排序的数组的大小:";
  65. int n;
  66. cin >> n;
  67. int* num = new int[n];
  68. int* num1 = new int[n];
  69. for (int i = 0; i < n; i++)
  70. {
  71. num[i] = rand();
  72. num1[i] = num[i];
  73. }
  74. clock_t start = clock();
  75. Choose_Sort(num, n);
  76. clock_t end = clock();
  77. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  78. //Print(num, n);
  79. clock_t start1 = clock();
  80. direct_sort(num1, n);
  81. clock_t end1 = clock();
  82. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  83. bool equal = true;
  84. for (int i = 0; i < n; i++)
  85. {
  86. if (num[i] != num1[i])
  87. {
  88. equal = false;
  89. break;
  90. }
  91. }
  92. if (equal)cout << "Right!" << endl;
  93. else cout << "Error!" << endl;
  94. delete[]num;
  95. delete[]num1;
  96. return 0;
  97. }

        该算法排序数组大小为100000的数组需要4945ms。经验证结果正确。

2.树形选择

        树形选择排序就是利用空间换取时间的思想。将一个数组弄成补成一个2的k次方的数组,多出来的部分用无穷大进行表示。这样我们就可以形成一个完全二叉树,并且每次对比都把2个中最小的一个数,赋值给该节点,这样头节点的数据就是这个数组中最小的数据。然后将这个数据赋值给原数组,并将该数设置为无穷大,进行下一轮迭代。这个算法的时间复杂度为O(nlogn)。

具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. #define M 0x7fffffff
  7. using namespace std;
  8. void Tree_Sort(int* a, int n);
  9. void Print(int* a, int n);
  10. void Swap(int& a, int& b);
  11. void direct_sort(int* a, int n);
  12. void Swap(int& a, int& b)
  13. {
  14. int temp = a;
  15. a = b;
  16. b = temp;
  17. }
  18. void Print(int* a, int n)
  19. {
  20. for (int i = 0; i < n; i++)
  21. {
  22. printf("%d ", a[i]);
  23. }
  24. cout << endl;
  25. }
  26. void direct_sort(int* a, int n)
  27. {
  28. if (n <= 1)
  29. {
  30. cout << "Array Error!" << endl;
  31. }
  32. for (int i = 1; i < n; i++)
  33. {
  34. int k = 0;
  35. while (a[i] > a[k])k++;
  36. int temp = a[i];
  37. for (int j = i; j > k; j--)
  38. {
  39. a[j] = a[j - 1];
  40. }
  41. a[k] = temp;
  42. }
  43. }
  44. void Tree_Sort(int* a, int n)
  45. {
  46. int n1 = n,t = 0;
  47. while (n1)
  48. {
  49. n1 >>= 1;
  50. t++;
  51. }
  52. int n2 = 1;
  53. n2 <<= t;
  54. int n_max = 2 * n2 - 1;
  55. int* num = new int[n_max];
  56. for (int i = 0; i < n2; i++)
  57. {
  58. if (i < n)num[i] = a[i];
  59. else num[i] = M;
  60. }
  61. for (int i = n2; i < n_max; i++)
  62. {
  63. num[i] = min(num[(i - n2) * 2], num[(i - n2) * 2 + 1]);
  64. }
  65. int h = n2;
  66. int pre1 = 0;
  67. for (int i = 0; i < 2 * n2 - 1; i++)
  68. {
  69. cout << num[i] << " ";
  70. if (i+1 == pre1 + h)
  71. {
  72. pre1 += h;
  73. cout << endl;
  74. h >>= 1;
  75. }
  76. }
  77. cout << endl;
  78. a[0] = num[n_max-1];
  79. for (int i = 0; i < n - 1; i++)
  80. {
  81. int temp = num[n_max - 1];
  82. int t = n_max - 1;
  83. while (t >= n2)
  84. {
  85. if (num[(t - n2) * 2] == temp)t = (t - n2) * 2;
  86. else t = (t - n2) * 2 + 1;
  87. }
  88. num[t] = M;
  89. while (t < n_max - 1)
  90. {
  91. num[n2 + t / 2] = min(num[t], num[t ^ 1]);
  92. t = n2 + t / 2;
  93. }
  94. a[i + 1] = num[n_max - 1];
  95. }
  96. delete[]num;
  97. }
  98. int main()
  99. {
  100. srand((unsigned)time(NULL));
  101. cout << "请输入待排序的数组大小:";
  102. int n;
  103. cin >> n;
  104. int* num = new int[n];
  105. int* num1 = new int[n];
  106. for (int i = 0; i < n; i++)
  107. {
  108. num[i] = rand();
  109. num1[i] = num[i];
  110. }
  111. clock_t start = clock();
  112. Tree_Sort(num, n);
  113. clock_t end = clock();
  114. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  115. //Print(num, n);
  116. clock_t start1 = clock();
  117. direct_sort(num1, n);
  118. clock_t end1 = clock();
  119. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  120. bool equal = true;
  121. for (int i = 0; i < n; i++)
  122. {
  123. if (num[i] != num1[i])
  124. {
  125. equal = false;
  126. break;
  127. }
  128. }
  129. if (equal)cout << "Right!" << endl;
  130. else cout << "Error!" << endl;
  131. delete[]num;
  132. delete[]num1;
  133. return 0;
  134. }

 

        该算法排序数组大小为100000的数组仅需要29ms,不过需要大量的空间来实现。经验证后结果正确。

三、交换排序

        交换排序就是不断的将大的数与小的数交换,将数组进行排序的算法。

1.冒泡排序

        冒泡排序就是不断地将大的数和小的数进行交换,大的数放在后面,把最大的数放在数组的末尾。当某一次遍历时若没有发生交换,说明该数组已经排序好了,这时候我们就可以break,跳出循环了。该算法的时间复杂度为O(n^2)。

具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. using namespace std;
  7. void Bubble_Sort(int* a, int n);
  8. void Print(int* a, int n);
  9. void Swap(int& a, int& b);
  10. void direct_sort(int* a, int n);
  11. void Swap(int& a, int& b)
  12. {
  13. int temp = a;
  14. a = b;
  15. b = temp;
  16. }
  17. void Print(int* a, int n)
  18. {
  19. for (int i = 0; i < n; i++)
  20. {
  21. printf("%d ", a[i]);
  22. }
  23. cout << endl;
  24. }
  25. void direct_sort(int* a, int n)
  26. {
  27. if (n <= 1)
  28. {
  29. cout << "Array Error!" << endl;
  30. }
  31. for (int i = 1; i < n; i++)
  32. {
  33. int k = 0;
  34. while (a[i] > a[k])k++;
  35. int temp = a[i];
  36. for (int j = i; j > k; j--)
  37. {
  38. a[j] = a[j - 1];
  39. }
  40. a[k] = temp;
  41. }
  42. }
  43. void Bubble_Sort(int* a, int n)
  44. {
  45. for (int i = 0; i < n; i++)
  46. {
  47. bool over = true;
  48. for (int j = 0; j < n - i - 1; j++)
  49. {
  50. if (a[j] > a[j + 1])
  51. {
  52. Swap(a[j], a[j + 1]);
  53. over = false;
  54. }
  55. }
  56. if (over)break;
  57. }
  58. }
  59. int main()
  60. {
  61. srand((unsigned)time(NULL));
  62. int n;
  63. cout << "请输入待排序的数组的大小:";
  64. cin >> n;
  65. int* num = new int[n];
  66. int* num1 = new int[n];
  67. for (int i = 0; i < n; i++)
  68. {
  69. num[i] = rand();
  70. num1[i] = num[i];
  71. }
  72. clock_t start = clock();
  73. Bubble_Sort(num, n);
  74. clock_t end = clock();
  75. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  76. //Print(num, n);
  77. clock_t start1 = clock();
  78. direct_sort(num1, n);
  79. clock_t end1 = clock();
  80. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  81. bool equal = true;
  82. for (int i = 0; i < n; i++)
  83. {
  84. if (num[i] != num1[i])
  85. {
  86. equal = false;
  87. break;
  88. }
  89. }
  90. if (equal)cout << "Right!" << endl;
  91. else cout << "Error!" << endl;
  92. delete[]num;
  93. delete[]num1;
  94. return 0;
  95. }

         该算法排序数组大小为100000的数组需要25806ms,时间开销较大。经验证后结果正确。

2.快速排序

         快速排序是在数组里面选取一个中间的数作为比较值,将比该值大的元素放在右边,比该元素小的元素放在左边。这样再对这个左右2个数组进行相同的操作,当两个边的边界值相差1时数组就已经排序好了。

        这里我们选取3个数进行比较选其中中间值,让中间值尽可能地接近该数组的中位数,来减少递归后的数组的时间复杂度,并且当数组足够小时,可以不需要递归调用,可以选择直接插入的算法进行排序,这样也可以减少时间复杂度。最终时间复杂度为O(nlogn)。

具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. using namespace std;
  7. void Quick_Sort(int* a, int n);
  8. void Quick_Divide(int* a, int left, int right);
  9. void Print(int* a, int n);
  10. void Swap(int& a, int& b);
  11. void direct_sort(int* a, int left,int right);
  12. void Swap(int& a, int& b)
  13. {
  14. int temp = a;
  15. a = b;
  16. b = temp;
  17. }
  18. void Print(int* a, int n)
  19. {
  20. for (int i = 0; i < n; i++)
  21. {
  22. printf("%d ", a[i]);
  23. }
  24. cout << endl;
  25. }
  26. void direct_sort(int* a, int left,int right)
  27. {
  28. if (left > right)
  29. {
  30. cout << "Array Error!" << endl;
  31. }
  32. for (int i = left + 1; i <= right; i++)
  33. {
  34. int k = left;
  35. while (a[i] > a[k])k++;
  36. int temp = a[i];
  37. for (int j = i; j > k; j--)
  38. {
  39. a[j] = a[j - 1];
  40. }
  41. a[k] = temp;
  42. }
  43. }
  44. void Quick_Divide(int* a, int left, int right)
  45. {
  46. if (right <= left)return;
  47. if (right - left < 10)
  48. {
  49. direct_sort(a, left, right);
  50. return;
  51. }
  52. int num[3] = { a[left],a[right],a[(left + right) / 2] };
  53. sort(num, num+3);
  54. int dex;
  55. if (num[1] == a[left])dex = left;
  56. else if (num[1] == a[right])dex = right;
  57. else dex = (left + right) / 2;
  58. Swap(a[dex], a[left]);
  59. int i = left, j = right;
  60. int temp = a[left];
  61. while (i < j)
  62. {
  63. while (i < j && a[i] < temp)i++;
  64. while (i < j && a[j] >= temp)j--;
  65. Swap(a[i], a[j]);
  66. }
  67. if (a[i] > temp)
  68. {
  69. Quick_Divide(a, left, i - 1);
  70. Quick_Divide(a, i, right);
  71. }
  72. else
  73. {
  74. Quick_Divide(a, left, i);
  75. Quick_Divide(a, i + 1, right);
  76. }
  77. }
  78. void Quick_Sort(int* a, int n)
  79. {
  80. Quick_Divide(a, 0, n - 1);
  81. }
  82. int main()
  83. {
  84. srand((unsigned)time(NULL));
  85. int n;
  86. cout << "请输入待排序的数组的大小:";
  87. cin >> n;
  88. int* num = new int[n];
  89. int* num1 = new int[n];
  90. for (int i = 0; i < n; i++)
  91. {
  92. num[i] = rand();
  93. num1[i] = num[i];
  94. }
  95. clock_t start = clock();
  96. Quick_Sort(num, n);
  97. clock_t end = clock();
  98. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  99. //Print(num, n);
  100. clock_t start1 = clock();
  101. direct_sort(num1, 0, n - 1);
  102. clock_t end1 = clock();
  103. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  104. bool equal = true;
  105. for (int i = 0; i < n; i++)
  106. {
  107. if (num[i] != num1[i])
  108. {
  109. equal = false;
  110. break;
  111. }
  112. }
  113. if (equal)cout << "Right!" << endl;
  114. else cout << "Error!" << endl;
  115. delete[]num;
  116. delete[]num1;
  117. return 0;
  118. }

         该算法排序数组大小为100000的数组仅需要14ms。经验证后结果正确。

 

四、其他排序

1.归并排序

        归并排序就是将数组逐步拆分为大小较小的数组,然后逐渐把数组进行合并这样就可以将时间复杂度降低到O(nlogn)了。

        注意:这里我们需要把原数组的大小拓展为2的k次方。

        具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. using namespace std;
  7. #define M 0x7fffffff
  8. void Merge_Sort(int* a, int n);
  9. void Print(int* a, int n);
  10. void Swap(int& a, int& b);
  11. void direct_sort(int* a, int n);
  12. void Merge(int* a, int n, int hn);
  13. void direct_sort(int* a, int n)
  14. {
  15. if (n <= 1)
  16. {
  17. cout << "Array Error!" << endl;
  18. }
  19. for (int i = 1; i < n; i++)
  20. {
  21. int k = 0;
  22. while (a[i] > a[k])k++;
  23. int temp = a[i];
  24. for (int j = i; j > k; j--)
  25. {
  26. a[j] = a[j - 1];
  27. }
  28. a[k] = temp;
  29. }
  30. }
  31. void Swap(int& a, int& b)
  32. {
  33. int temp = a;
  34. a = b;
  35. b = temp;
  36. }
  37. void Merge_Sort(int* a, int n)
  38. {
  39. //Print(a, n);
  40. int t = 0;
  41. int n1 = n;
  42. while (n1)
  43. {
  44. n1 >>= 1;
  45. t++;
  46. }
  47. int n2 = 1;
  48. for (int i = 0; i < t; i++)
  49. {
  50. n2 <<= 1;
  51. }
  52. int* num = new int[n2];
  53. for (int i = 0; i < n; i++)
  54. {
  55. num[i] = a[i];
  56. }
  57. for (int i = n; i < n2; i++)
  58. {
  59. num[i] = M;
  60. }
  61. for (int i = 0; i < n2 / 2; i++)
  62. {
  63. if (num[2 * i] > num[2 * i + 1])Swap(num[2 * i], num[2 * i + 1]);
  64. }
  65. int hn = 2;
  66. while (hn <= n2 / 2)
  67. {
  68. Merge(num, n2, hn);
  69. hn <<= 1;
  70. //Print(num, n);
  71. }
  72. //Print(num, n2);
  73. for (int i = 0; i < n; i++)
  74. {
  75. a[i] = num[i];
  76. }
  77. //Print(a, n);
  78. }
  79. void Merge(int* num, int n, int hn)
  80. {
  81. int* num1 = new int[n];
  82. for (int i = 0; i < n; i++)
  83. {
  84. num1[i] = num[i];
  85. }
  86. int t = 2 * hn;
  87. for (int i = 0; i < n / t; i++)
  88. {
  89. int start = i * t, end = start + t - 1, k = start, p1 = start, p2 = start + hn;
  90. while (p1 < start + hn && p2<=end)
  91. {
  92. if (num1[p1] <= num[p2])
  93. {
  94. num[k++] = num1[p1++];
  95. //if (k == 1)cout << num[0] << endl;
  96. }
  97. else
  98. {
  99. num[k++] = num1[p2++];
  100. //if (k == 1)cout << num[0] << endl;
  101. }
  102. }
  103. while (p1 < start + hn)num[k++] = num1[p1++];
  104. while (p2 <= end)num[k++] = num1[p2++];
  105. }
  106. delete[]num1;
  107. }
  108. void Print(int* a, int n)
  109. {
  110. for (int i = 0; i < n; i++)
  111. {
  112. printf("%d ",a[i]);
  113. //if ((i+1) % gap == 0)cout << endl;
  114. }
  115. cout << endl;
  116. }
  117. int main()
  118. {
  119. srand((unsigned)time(NULL));
  120. cout << "请输入待排序的数组的大小:";
  121. int n;
  122. cin >> n;
  123. int* num = new int[n];
  124. int* num1 = new int[n];
  125. for (int i = 0; i < n; i++)
  126. {
  127. num[i] = rand();
  128. num1[i] = num[i];
  129. }
  130. clock_t start = clock();
  131. Merge_Sort(num, n);
  132. clock_t end = clock();
  133. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  134. //Print(num, n);
  135. clock_t start1 = clock();
  136. direct_sort(num1, n);
  137. clock_t end1 = clock();
  138. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  139. bool equal = true;
  140. for (int i = 0; i < n; i++)
  141. {
  142. if (num[i] != num1[i])
  143. {
  144. equal = false;
  145. break;
  146. }
  147. }
  148. if (equal)cout << "Right!" << endl;
  149. else cout << "Error!" << endl;
  150. delete[]num;
  151. delete[]num1;
  152. return 0;
  153. }

        该算法排序数组大小为100000的数组仅需要15ms。经验证后结果正确。

2.基数排序

        基数排序,就是以某一个进制为基础,将该数组分为若干个数组(几进制就用几个数组),将余数相同的数放在一个数组里,然后将这个数右移一位。这里需要找到,最大的一个数的最高位次,就可以知道需要迭代多少轮了。这样排序后都是按照位次一步一步排序好的,所以最后结果也是对的,不过这个需要大量的空间去存放数据。时间复杂度为O(nlogn)。

具体代码为:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <algorithm>
  5. #include <time.h>
  6. using namespace std;
  7. void Base_Sort(int* a, int n);
  8. void Print(int* a, int n);
  9. void Swap(int& a, int& b);
  10. void direct_sort(int* a, int n);
  11. void Base_Sort_pre(int* a, int n, int loop);
  12. void direct_sort(int* a, int n)
  13. {
  14. if (n <= 1)
  15. {
  16. cout << "Array Error!" << endl;
  17. }
  18. for (int i = 1; i < n; i++)
  19. {
  20. int k = 0;
  21. while (a[i] > a[k])k++;
  22. int temp = a[i];
  23. for (int j = i; j > k; j--)
  24. {
  25. a[j] = a[j - 1];
  26. }
  27. a[k] = temp;
  28. }
  29. }
  30. void Swap(int& a, int& b)
  31. {
  32. int temp = a;
  33. a = b;
  34. b = temp;
  35. }
  36. void Print(int* a, int n)
  37. {
  38. for (int i = 0; i < n; i++)
  39. {
  40. printf("%d ", a[i]);
  41. //if ((i+1) % gap == 0)cout << endl;
  42. }
  43. cout << endl;
  44. }
  45. void Base_Sort_pre(int* a, int n,int loop)
  46. {
  47. //cout << t << endl;
  48. int d[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 };
  49. int* bucket[10] = { };
  50. int c[10] = { 0 };
  51. for (int j = 0; j < n; j++)
  52. {
  53. c[(a[j] / d[loop]) % 10]++;
  54. }
  55. for (int k = 0; k < 10; k++)
  56. {
  57. bucket[k] = (int*)malloc(c[k] * sizeof(int));
  58. }
  59. for (int m = 0; m < 10; m++)c[m] = 0;
  60. for (int l = 0; l < n; l++)
  61. {
  62. int row = (a[l] / d[loop]) % 10;
  63. bucket[row][c[row]] = a[l];
  64. c[row]++;
  65. }
  66. int s = 0;
  67. for (int x = 0; x < 10; x++)
  68. {
  69. for (int y = 0; y < c[x]; y++)
  70. {
  71. a[s] = bucket[x][y];
  72. s++;
  73. }
  74. }
  75. for (int p = 0; p < 10; p++)
  76. {
  77. free(bucket[p]);
  78. }
  79. }
  80. void Base_Sort(int* a, int n)
  81. {
  82. int ma = 0;
  83. for (int i = 0; i < n; i++)
  84. {
  85. if (a[i] > ma)ma = a[i];
  86. }
  87. int t = 0;
  88. int ai = ma;
  89. //cout << ai << endl;
  90. while (ai)
  91. {
  92. ai /= 10;
  93. t++;
  94. }
  95. for (int i = 0; i < t; i++)
  96. {
  97. Base_Sort_pre(a, n, i);
  98. }
  99. }
  100. int main()
  101. {
  102. srand((unsigned)time(NULL));
  103. cout << "请输入待排序的数组的大小:";
  104. int n;
  105. cin >> n;
  106. int* num = new int[n];
  107. int* num1 = new int[n];
  108. for (int i = 0; i < n; i++)
  109. {
  110. num[i] = rand();
  111. num1[i] = num[i];
  112. }
  113. clock_t start = clock();
  114. Base_Sort(num, n);
  115. clock_t end = clock();
  116. cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  117. //Print(num, n);
  118. clock_t start1 = clock();
  119. direct_sort(num1,n);
  120. clock_t end1 = clock();
  121. cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
  122. bool equal = true;
  123. for (int i = 0; i < n; i++)
  124. {
  125. if (num[i] != num1[i])
  126. {
  127. equal = false;
  128. break;
  129. }
  130. }
  131. //printf("%d\n", equal);
  132. if (equal)cout << "Right!" << endl;
  133. else cout << "Error!" << endl;
  134. delete[]num;
  135. delete[]num1;
  136. return 0;
  137. }

        该算法排序数组大小为100000的数组仅需要13ms。经验证结果正确。

 


总结

        这个9种排序算法的时间快慢为:基数排序>快速排序>归并排序>希尔排序>树形排序>折半插入>直接选择>直接插入>冒泡排序。

         其中,空间开销较大的有:基数排序和树形排序。

        每个排序算法都有自己的用途,不能单独从时间快慢上判断这个排序算法的好坏!

        以上代码为本人自己原创,可能有许多错误和理解不到位的地方,还望各位大佬指正!!!

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号