[关闭]
@CrazyHenry 2018-03-07T17:39:36.000000Z 字数 4186 阅读 984

0.x 10.快速排序

dddd数据结构课本


优化快速排序(递归到底使用插入排序)

1520407554242.jpg-2909kB

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <iterator>
  5. #include <algorithm>
  6. #include <typeinfo>
  7. #include <numeric>
  8. #include <memory>
  9. #include <stdexcept>
  10. #include <fstream>
  11. #include <sstream>
  12. using namespace std;
  13. //win+<-/-> 切换窗口位置
  14. //ctrl+win+<-/->切换桌面
  15. //ctrl+alt+上/下 改变显示器方向
  16. template <typename T>
  17. int __partition(T arr[], int l, int r){
  18. T v = arr[l];
  19. int j = l + 1; // arr[l+1...j) < v ; arr[j...i) >= v
  20. for( int i = l + 1 ; i != r ; i ++ )
  21. if( arr[i] < v ){
  22. swap( arr[j++] , arr[i] );
  23. }
  24. swap( arr[l] , arr[--j]);//轴值要与j左边的那个<v的元素交换
  25. //返回轴值的位置
  26. return j;
  27. }
  28. // 对arr[l...r]部分进行快速排序
  29. template <typename T>
  30. void __quickSort(T arr[], int l, int r){
  31. if( l >= r-1 ) //这里递归到底可以使用直接插入排序
  32. return;
  33. int p = __partition(arr, l, r);
  34. __quickSort(arr, l, p );
  35. __quickSort(arr, p+1, r);
  36. }
  37. template <typename T>
  38. void quickSort(T arr[], int n){
  39. __quickSort(arr, 0, n);
  40. }
  41. int main() {
  42. int a[20] = {120,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1};
  43. quickSort(a,20);
  44. for( int i = 0 ; i < 20 ; ++i )
  45. cout<<a[i]<<ends;
  46. cout<<endl;
  47. return 0;
  48. }

随机化快速排序(正序或者逆序)

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <iterator>
  5. #include <algorithm>
  6. #include <typeinfo>
  7. #include <numeric>
  8. #include <memory>
  9. #include <stdexcept>
  10. #include <fstream>
  11. #include <sstream>
  12. #include <random>
  13. using namespace std;
  14. //win+<-/-> 切换窗口位置
  15. //ctrl+win+<-/->切换桌面
  16. //ctrl+alt+上/下 改变显示器方向
  17. template <typename T>
  18. int __partition(T arr[], int l, int r){
  19. static default_random_engine e;
  20. //分布类型不能用static,因为每次调用的时候都需要修改l和r-1
  21. uniform_int_distribution<unsigned> u(l,r-1);//C++的随机数引擎
  22. swap(arr[l], arr[u(e)]);
  23. T v = arr[l];
  24. int j = l + 1; // arr[l+1...j) < v ; arr[j...i) >= v
  25. for( int i = l + 1 ; i != r ; ++i )
  26. if( arr[i] < v ){
  27. swap( arr[j++] , arr[i] );
  28. }
  29. swap( arr[l] , arr[--j]);
  30. return j;
  31. }
  32. // 对arr[l...r]部分进行快速排序
  33. template <typename T>
  34. void __quickSort(T arr[], int l, int r){
  35. if( l >= r-1 )
  36. return;
  37. int p = __partition(arr, l, r);
  38. __quickSort(arr, l, p );
  39. __quickSort(arr, p+1, r);
  40. }
  41. template <typename T>
  42. void quickSort(T arr[], int n){
  43. __quickSort(arr, 0, n);
  44. }
  45. int main() {
  46. int a[20] = {120,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1};
  47. quickSort(a,20);
  48. for( int i = 0 ; i < 20 ; ++i)
  49. cout<<a[i]<<ends;
  50. cout<<endl;
  51. return 0;
  52. }

二路快排(大量重复元素)

略,意义不大,性能不及三路。

三路快排(大量重复,比二路更强)

1520407395653.jpg-2855.5kB

  1. template <typename T>
  2. pair<int,int> __partition(T arr[], int l, int r)
  3. {
  4. T v = arr[l];
  5. int lt = l + 1; // arr[l+1...lt) < v
  6. int gt = r; // arr[gt...r) > v
  7. int i = l+1; // arr[lt+1...i) == v
  8. while( i != gt ){
  9. if( arr[i] < v ){
  10. swap( arr[i++], arr[lt++]);
  11. }
  12. else if( arr[i] > v ){
  13. swap( arr[i], arr[--gt]);
  14. }
  15. else{ // arr[i] == v
  16. ++i;
  17. }
  18. }
  19. swap( arr[l] , arr[--lt] );
  20. return {lt,gt};
  21. }
  22. // 递归的三路快速排序算法
  23. template <typename T>
  24. void __quickSort3Ways(T arr[], int l, int r){
  25. if( l >= r-1 ) //一定要考虑到r==l的情况也可能发生,直接return
  26. return;
  27. auto p = __partition(arr, l, r);
  28. __quickSort3Ways(arr, l, p.first);
  29. __quickSort3Ways(arr, p.second, r);
  30. }
  31. template <typename T>
  32. void quickSort3Ways(T arr[], int n){
  33. __quickSort3Ways( arr, 0, n);
  34. }
  35. int main() {
  36. int a[20] = {120,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1};
  37. quickSort3Ways(a,20);
  38. for( int i = 0 ; i < 20 ; ++i )
  39. cout<<a[i]<<ends;
  40. cout<<endl;
  41. return 0;
  42. }

终极版本(优化的三路随机快排)

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <iterator>
  5. #include <algorithm>
  6. #include <typeinfo>
  7. #include <numeric>
  8. #include <memory>
  9. #include <stdexcept>
  10. #include <fstream>
  11. #include <utility>
  12. #include <sstream>
  13. #include <random>
  14. using namespace std;
  15. //win+<-/-> 切换窗口位置
  16. //ctrl+win+<-/->切换桌面
  17. //ctrl+alt+上/下 改变显示器方向
  18. template <typename T>
  19. pair<int,int> __partition(T arr[], int l, int r)
  20. {
  21. static default_random_engine e;
  22. uniform_int_distribution<unsigned> u(l,r-1);//C++的随机数引擎
  23. swap(arr[l], arr[u(e)]);
  24. T v = arr[l];
  25. int lt = l + 1; // arr[l+1...lt) < v
  26. int gt = r; // arr[gt...r) > v
  27. int i = l+1; // arr[lt+1...i) == v
  28. while( i != gt ){
  29. if( arr[i] < v ){
  30. swap( arr[i++], arr[lt++]);
  31. }
  32. else if( arr[i] > v ){
  33. swap( arr[i], arr[--gt]);
  34. }
  35. else{ // arr[i] == v
  36. ++i;
  37. }
  38. }
  39. swap( arr[l] , arr[--lt] );
  40. return {lt,gt};
  41. }
  42. // 递归的三路快速排序算法
  43. template <typename T>
  44. void __quickSort3Ways(T arr[], int l, int r){
  45. // 对于小规模数组, 可以使用插入排序进行优化
  46. //if( r-l <= 1) return;
  47. if(r - l <= 10)//少于10个数
  48. {
  49. if(l == r) return;//0个元素
  50. for(int i = l + 1; i != r; ++i)
  51. {
  52. int temp = arr[i];
  53. int j = 0;//初始化
  54. for(j = i; j != l && temp < arr[j - 1]; --j)
  55. {
  56. arr[j] = arr[j - 1];
  57. }
  58. arr[j] = temp;
  59. }
  60. return;
  61. }
  62. auto p = __partition(arr, l, r);
  63. __quickSort3Ways(arr, l, p.first);
  64. __quickSort3Ways(arr, p.second, r);
  65. }
  66. template <typename T>
  67. void quickSort3Ways(T arr[], int n){
  68. __quickSort3Ways( arr, 0, n);
  69. }
  70. int main() {
  71. int a[40] = {120,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1,120,9,8,7,6,5,4,3,2,1,10,9,8,7,6,5,4,3,2,1};
  72. quickSort3Ways(a,40);
  73. for( int i = 0 ; i < 40 ; ++i )
  74. cout<<a[i]<<ends;
  75. cout<<endl;
  76. return 0;
  77. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注