ToB企服应用市场:ToB评测及商务社交产业平台

标题: 快速排序 [打印本页]

作者: 自由的羽毛    时间: 2022-9-16 17:25
标题: 快速排序
快速排序

快速排序是一种分治的递归算法,平均时间复杂度:O(NlogN)
1.1 基础版
  1. //递归方法
  2. int parition(vector<int> &arry, int left, int right) {
  3.     int pivotkey; //枢轴值
  4.     pivotkey = arry[left];
  5.     while (left < right) {
  6.         while (pivotkey<= arry[right] && left < right) right--;
  7.             //将比枢轴值小的记录交换到左端
  8.             swap(arry[left], arry[right]);
  9.         while (pivotkey >= arry[left] && left < right) left++;
  10.             //将比枢轴值大的记录交换到右端
  11.             swap(arry[left], arry[right]);
  12.     }
  13.     return left;
  14. }
  15. //快速排序
  16. void QSort(vector<int> &arry, int left, int right) {
  17.     if (left < right) {
  18.         int pivot = parition(arry, left, right);
  19.         QSort(arry, left, pivot- 1);
  20.         QSort(arry, pivot+ 1, right);
  21.     }
  22. }
复制代码
1.2 优化

1.2.1 优化选取枢轴值

三数取中法,这样可以避免取到最大值或最小值
  1. int parition(vector<int> &arry,, int left, int right) {
  2.     int pivotkey; //枢轴值优化选取
  3.     int mid = left + (right - left) / 2;
  4.     //将中间值放在最左端
  5.     if(arry[left] > arry[right]){
  6.         swap(arry[left], arry[right]);
  7.     }
  8.     if(arry[mid] > arry[right]){
  9.         swap(arry[mid], arry[right]);
  10.     }
  11.     if(arry[mid] < arry[left]){
  12.         swap(arry[mid], arry[left]);
  13.     }
  14.     //选取中间值
  15.     pivotkey = arry[left];
  16.     while (left < right) {
  17.         while (pivotkey<= arry[right] && left < right) right--;
  18.             //将比枢轴值小的记录交换到左端
  19.             swap(arry[left], arry[right]);
  20.         while (pivotkey >= arry[left] && left < right) left++;
  21.             //将比枢轴值大的记录交换到右端
  22.             swap(arry[left], arry[right]);
  23.     }
  24.     return left;
  25. }
复制代码
1.2.2 优化不必要的交换

将关键字采取替换的方式代替交换
  1. int parition(vector<int> &arry, int left, int right) {
  2.     int pivotkey; //枢轴值优化选取
  3.     int mid = left + (right - left) / 2;
  4.     //将中间值放在最左端
  5.     if(arry[left] > arry[right]){
  6.         swap(arry[left], arry[right]);
  7.     }
  8.     if(arry[mid] > arry[right]){
  9.         swap(arry[mid], arry[right]);
  10.     }
  11.     if(arry[mid] < arry[left]){
  12.         swap(arry[mid], arry[left]);
  13.     }
  14.     //选取中间值
  15.     pivotkey = arry[left];
  16.     while (left < right) {
  17.         while (pivotkey<= arry[right] && left < right) right--;
  18.         //将比枢轴值小的记录交换到左端
  19.         arry[left] = arry[right];
  20.         while (pivotkey >= arry[left] && left < right) left++;
  21.         //将比枢轴值大的记录交换到右端
  22.         arry[right] = arry[left];   
  23.     }
  24.     arry[left] = pivotkey
  25.     return left;
  26. }
复制代码
1.2.3 优化小数组的排序方案

如果数组长度比较小那么快速排序不如插入排序来的简单
插入排序
  1. void insertSort(vector<int> &arry, int left, int right)
  2. {
  3.     // 注意下标从left开始
  4.     for (int i = left; i <= right; i++) {
  5.         int temp = arry[i];
  6.         int j;
  7.         for (j = i - 1; j >= left && arry[j] > temp; j--) {
  8.             arry[j + 1] = arry[j];
  9.         }
  10.         arry[j + 1] = temp;
  11.      }
  12. }
复制代码
优化后的快速排序
//快速排序
  1. const max_insert_length = 20; // 我也不知道中介值在哪
  2. void QSort(vector<int> &arry, int left, int right) {
  3.     if((right - left) > max_insert_length){
  4.         if (left < right) {
  5.             int pivot = parition(arry, left, right);
  6.             QSort(arry, left, pivot- 1);
  7.             QSort(arry, pivot+ 1, right);
  8.         }
  9.     }else{
  10.         insertSort(arry, int left, int right)
  11.     }
  12. }
复制代码
1.2.4 优化递归操作

减少使用递归
  1. const max_insert_length = 20; // 我也不知道中介值在哪
  2. void QSort(vector<int> &arry, int left, int right) {
  3.     if((right - left) > max_insert_length){
  4.         while (left < right) {
  5.             int pivot = parition(arry, left, right);
  6.             QSort(arry, left, pivot- 1);
  7.             left = pivot + 1; // 尾递归
  8.         }
  9.     }else{
  10.         insertSort(arry, int left, int right)
  11.     }
  12. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4