<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      快速排序及優(yōu)化

      快速排序

      每次從當(dāng)前考慮的數(shù)組中選一個(gè)元素,把這個(gè)元素想辦法挪到應(yīng)該排好序的位置,比如4這個(gè)元素,它就有一個(gè)性質(zhì)4之前的元素都是小于它的,之后的元素都是大于它的,之后我們要做的事情是對小于4和大于4的數(shù)組分別繼續(xù)使用快速排序的思路,逐漸遞歸下去完成整個(gè)排序過程。

      在這里插入圖片描述
      對于快速排序如果把選定的元素挪到正確的位置的過程也是快速排序的核心,在這個(gè)過程中我們通常選擇數(shù)組第一個(gè)元素為我們分界的標(biāo)志點(diǎn),我們記錄這個(gè)點(diǎn)為 l ,之后我們逐漸的遍歷右邊所有沒有被訪問的元素,在遍歷的過程中我們逐漸整理一部分是小于v這個(gè)元素的,一部分是大于v這個(gè)元素的,當(dāng)讓我們要有個(gè)記錄那個(gè)是小于v和大于v的分界點(diǎn),這個(gè)點(diǎn)為 j ,而當(dāng)前訪問的元素記錄為 i
      在這里插入圖片描述
      我們?nèi)绾蝸頉Q定當(dāng)前的元素要怎樣變化才能維持當(dāng)前的性質(zhì),如果當(dāng)前的元素e是比v還要大的,那么他直接就放在大于v一部分的后面。
      在這里插入圖片描述
      然后就考慮下一元素就好了。
      在這里插入圖片描述
      如果當(dāng)前的元素e是比v還要小的。
      在這里插入圖片描述
      我們只需要當(dāng)前橙色部分也就是j所指的位置的后一個(gè)元素和當(dāng)前做考察的元素 i進(jìn)行一下交換 。
      在這里插入圖片描述
      之后我們進(jìn)行一下位置維護(hù) ++j++i

      在這里插入圖片描述
      以此類推,整個(gè)數(shù)組分成三個(gè)部分,第一個(gè)元素是v,橙色部分小于v,紫色部分大于v
      在這里插入圖片描述
      最后我們需要做的是把數(shù)組 l這個(gè)位置和數(shù)組j這個(gè)位置進(jìn)行交換,這樣整個(gè)數(shù)組就形成了我們設(shè)想的那樣,前面小于v,后面大于v
      在這里插入圖片描述

      優(yōu)化

      • 對于小規(guī)模數(shù)組, 使用插入排序進(jìn)行優(yōu)化;
      • 隨機(jī)在arr[l...r]的范圍中, 選擇一個(gè)數(shù)值作為標(biāo)定點(diǎn)pivot。在快速排序遞歸過程中分成的子樹不能保證每次都是平均的將整個(gè)數(shù)組一分為二,換句話來說分成的子數(shù)組可能是一大一小的。
      • 在這里插入圖片描述
      • 如果數(shù)組近乎或完全有序那么:
      • 在這里插入圖片描述

      quickSort

      // 對arr[l...r]范圍的數(shù)組進(jìn)行插入排序
      template<typename T>
      void insertionSort(T arr[], int l, int r) {
         for (int i = l + 1; i <= r; ++i) {
             T e = arr[i];
             int j;
             for (j = i; j > l && arr[j - 1] > e; --j) {
                 arr[j] = arr[j - 1];
             }
             arr[j] = e;
         }
      }
      
      // 對arr[l...r]部分進(jìn)行partition操作
      // 返回p, 使得arr[l...p-1] < arr[p] ; arr[p+1...r] > arr[p]
      template<typename T>
      int __partition1(T arr[], const int l, const int r) {
         // 優(yōu)化:隨機(jī)在arr[l...r]的范圍中, 選擇一個(gè)數(shù)值作為標(biāo)定點(diǎn)pivot
         std::swap(arr[l], arr[rand() % (r - l + 1) + l]);
         const T v = arr[l];
         int j = l;
         // arr[l+1...j] < v ; arr[j+1...i) > v
         for (int i = l + 1; i <= r; ++i) {
             if (arr[i] < v) {
                 std::swap(arr[++j], arr[i]);
             }
         }
         std::swap(arr[l], arr[j]);
         return j;
      }
      // 對arr[l...r]部分進(jìn)行快速排序
      template<typename T>
      void __quickSort(T arr[], const int l, const int r) {
         // 優(yōu)化:對于小規(guī)模數(shù)組, 使用插入排序進(jìn)行優(yōu)化
         if (r - l <= 15) {
             insertionSort(arr, l, r);
             return;
         }
         const int p = __partition1(arr, l, r);
         __quickSort(arr, l, p - 1);
         __quickSort(arr, p + 1, r);
      }
      
      //快速排序
      template<typename T>
      void quickSort(T arr[], const int n) {
         srand(time(NULL));
         __quickSort(arr, 0, n - 1);
      } 
      

      雙路快速排序

      在之前的快速排序我們沒有討論在等于v的情況,在這里無論是把等于放在左邊還是右邊,如果整個(gè)數(shù)組出現(xiàn)大量重復(fù)的元素,那么它就會造成左右分成的數(shù)組極度不平衡從而使算法退化成O(n^2)

      現(xiàn)在呢我們將小于v和大于v放在數(shù)組的兩端。首先我們從i這個(gè)位置開始向后掃描,當(dāng)我們面對的元素仍然是小于v的時(shí)候我們繼續(xù)向后掃描,知道我們碰到了元素e,它是大于等于v的。
      在這里插入圖片描述
      同樣 j 亦是如此,
      在這里插入圖片描述

      這樣話兩個(gè)綠色的部分就分別歸并到橙色和紫色。
      在這里插入圖片描述
      ij這兩個(gè)所指的元素交換一下位置就可以了。
      在這里插入圖片描述
      然后維護(hù)一下位置 ++i--j,以此類推。
      在這里插入圖片描述

      quickSort2Ways

      // 對arr[l...r]范圍的數(shù)組進(jìn)行插入排序
      template<typename T>
      void insertionSort(T arr[], int l, int r) {
         for (int i = l + 1; i <= r; ++i) {
             T e = arr[i];
             int j;
             for (j = i; j > l && arr[j - 1] > e; --j) {
                 arr[j] = arr[j - 1];
             }
             arr[j] = e;
         }
      }
      
      // 雙路快速排序的partition
      // 返回p, 使得arr[l...p-1] <= arr[p] ; arr[p+1...r] >= arr[p]
      // 雙路快排處理的元素正好等于arr[p]的時(shí)候要注意,詳見下面的注釋:)
      template<typename T>
      int __partition2(T arr[], int l, int r) {
         // 隨機(jī)在arr[l...r]的范圍中, 選擇一個(gè)數(shù)值作為標(biāo)定點(diǎn)pivot
         std::swap(arr[l], arr[rand() % (r - l + 1) + l]);
         const T v = arr[l];
         // arr[l+1...i) <= v; arr(j...r] >= v
         int i = l + 1, j = r;
         while (true) {
             // 注意這里的邊界, arr[i] < v, 不能是arr[i] <= v
             // 思考一下為什么?
             while (i <= r && arr[i] < v)++i;
             // 注意這里的邊界, arr[j] > v, 不能是arr[j] >= v
             // 思考一下為什么?
             while (j >= l + 1 && arr[j] > v)--j;
             if (i > j)break;
             std::swap(arr[i], arr[j]);
             //arr[i] < v. 在碰到很多連續(xù)相同數(shù)字的情況下,i只向后移動一次,同時(shí)j至少向前移動一次,相對平衡。
             //arr[i] <= vb, 在碰到很多連續(xù)相同數(shù)字的情況下, i首先不停向后移動,直到滿足條件為止,造成不平衡。
             ++i;
             --j;
         }
         std::swap(arr[l], arr[j]);
         return j;
      }
      
      // 對arr[l...r]部分進(jìn)行快速排序
      template<typename T>
      void __quickSort2Ways(T arr[], const int l, const int r) {
         // 對于小規(guī)模數(shù)組, 使用插入排序進(jìn)行優(yōu)化
         if (r - l <= 15) {
             insertionSort(arr, l, r);
             return;
         }
         const int p = __partition2(arr, l, r);
         __quickSort2Ways(arr, l, p - 1);
         __quickSort2Ways(arr, p + 1, r);
      }
      
      //快速排序
      template<typename T>
      void quickSort2Ways(T arr[], const int n) {
         srand(time(NULL));
         __quickSort2Ways(arr, 0, n - 1);
      }
      

      三路快速排序

      之前快速排序的思想都是小于v大于v,而三路快速排序的思想是小于v等于v大于v。在這樣分割之后在遞歸的過程中,對于等于v的我們根本不用管了,只需要遞歸小于v大于v的部分進(jìn)行同樣的快速排序。
      在這里插入圖片描述
      現(xiàn)在我們要處理i位置這個(gè)元素e,如果當(dāng)前元素 e 正好等于v,那么元素e就直接納入綠色的等于v的部分,相應(yīng)的 ++i,我們來處理下一位置的元素。
      在這里插入圖片描述
      如果當(dāng)前元素 e 小于v,我們只需要把這個(gè)元素和等于v部分的第一個(gè)元素進(jìn)行一次交換就好了。
      在這里插入圖片描述
      之后因該維護(hù)一下位置,++i++lt,來查看下一元素。
      在這里插入圖片描述
      如果當(dāng)前元素 e 大于v,我們只需要把這個(gè)元素和gt-1位置的元素進(jìn)行一次交換就好了。
      在這里插入圖片描述
      相應(yīng)的我們應(yīng)該維護(hù)一下gt的位置 --gt,需要注意的是i我們不需要?jiǎng)铀驗(yàn)楹退粨Q的位置元素本就沒有討論過。
      在這里插入圖片描述
      以此類推,最后還需要llt位置的元素交換一下位置。
      在這里插入圖片描述
      此時(shí)我們整個(gè)數(shù)組就變成了這個(gè)樣子,之后我們只需要對小于v的部分和大于v的部分進(jìn)行遞歸的快速排序就好了,至于等于v的部分它已經(jīng)放在數(shù)組合適的位置了。
      在這里插入圖片描述

      quickSort3Ways

      // 對arr[l...r]范圍的數(shù)組進(jìn)行插入排序
      template<typename T>
      void insertionSort(T arr[], int l, int r) {
         for (int i = l + 1; i <= r; ++i) {
             T e = arr[i];
             int j;
             for (j = i; j > l && arr[j - 1] > e; --j) {
                 arr[j] = arr[j - 1];
             }
             arr[j] = e;
         }
      }
      
      // 遞歸的三路快速排序算法
      template<typename T>
      void __quickSort3Ways(T arr[], const int l, const int r) {
         // 對于小規(guī)模數(shù)組, 使用插入排序進(jìn)行優(yōu)化
         if (r - l <= 15) {
             insertionSort(arr, l, r);
             return;
         }
      
         // 隨機(jī)在arr[l...r]的范圍中, 選擇一個(gè)數(shù)值作為標(biāo)定點(diǎn)pivot
         std::swap(arr[l], arr[rand() % (r - l + 1) + l]);
      
         T v = arr[l];
      
         int lt = l;     // arr[l+1...lt] < v
         int gt = r + 1; // arr[gt...r] > v
         int i = l + 1;    // arr[lt+1...i) == v
         while (i < gt) {
             if (arr[i] < v) {
                 std::swap(arr[i], arr[lt + 1]);
                 ++i;
                 ++lt;
             } else if (arr[i] > v) {
                 std::swap(arr[i], arr[gt - 1]);
                 --gt;
             } else { // arr[i] == v
                 ++i;
             }
         }
         std::swap(arr[l], arr[lt]);
         __quickSort3Ways(arr, l, lt - 1);
         __quickSort3Ways(arr, gt, r);
      }
      
      // 對于包含有大量重復(fù)數(shù)據(jù)的數(shù)組, 三路快排有巨大的優(yōu)勢
      template<typename T>
      void quickSort3Ways(T arr[], const int n) {
         srand(time(nullptr));
         __quickSort3Ways(arr, 0, n - 1);
      }
      

      概述

      在這里插入圖片描述
      在這里插入圖片描述

      posted @ 2022-07-20 01:34  放飛夢想C  閱讀(655)  評論(2)    收藏  舉報(bào)
      主站蜘蛛池模板: 精品人妻免费看一区二区三区| 亚洲另类激情专区小说图片| 免费无码一区二区三区蜜桃| 国产福利社区一区二区| 国产精品亚洲一区二区三区| 国产三级精品福利久久| 国产成人综合网亚洲第一| 亚洲欧洲日韩国内高清| 久久丫精品国产| 久久三级国内外久久三级| 亚洲精品一二三在线观看| 国色天香中文字幕在线视频| 久久精产国品一二三产品| 国产午夜精品福利免费不| 最新国产精品拍自在线观看| 亚洲AVAV天堂AV在线网阿V| 日本夜爽爽一区二区三区| 成人免费视频在线观看播放| 台北市| 国产91精品一区二区蜜臀| 97人人添人人澡人人澡人人澡| 久久亚洲熟女cc98cm| 中文无码精品a∨在线| 国产91午夜福利精品| 国产乱理伦片在线观看| 欧美黑人巨大videos精品| 亚洲不卡一区二区在线看| 婷婷六月天在线| 久久久精品2019中文字幕之3| 十八禁日本一区二区三区| 久久精品国产免费观看频道| 毛片网站在线观看| 一区二区三区一级黄色片| 国产自在自线午夜精品| 亚洲v欧美v日韩v国产v| 国产在线精品中文字幕| 免费国产女王调教在线视频| 成人亚洲一级午夜激情网| 日韩精品亚洲专在线电影| 久久国产成人精品av| 噜噜综合亚洲av中文无码|