您好,登錄后才能下訂單哦!
書接上文,上次講到了雙路快速排序,雙路快速排序是將等于v(標志數)的數也進行交換,從而避免了在處理有大量重復數據的數組分組時的不平衡。而三路快速排序則是將等于v的數也分成一組,同樣可以解決上述問題。其原理如下:
1、采用隨機排序的方法將某個數作為分割數,放在數組開頭,該數定義為v。將小于v的一段數組開頭的數索引定義為lt,將需要遍歷的數組的索引定義為i,將小于v的一段數組的索引定義為gt,數組的開頭和結尾的索引分別為l和r。原理圖如下:
2、對索引i進行維護,逐個比較索引i對應的數與v的關系。如果arr[i]<v,那么將arr[i]和arr[lt+1]交換,之后將索引i和lt分別向后移動一位。如下圖藍色的e和灰綠色的那塊相交換
3、如果arr[i]=v,則將arr[i]納入等于v的那一部分,之后將索引i向后移動一位
4、如果arr[i]>v,則將arr[i]與arr[gt-1]交換位置,之后將索引gt向前移動一位,但是要注意,這時,索引i不需要移動,因為交換過來的數不知道大小,下一步還需要接著判斷。
5、按照這個流程,gt會和i重合,則結束比較的過程
6、最后,不要忘了將arr[l]和arr[lt]交換位置,注意:這里交換位置的是arr[lt]。排序完成
代碼如下:
#ifndef QUICKSORT3_H #define QUICKSORT3_H //三路快速排序算法 #include <iostream> #include <stdlib.h> using namespace std; template <typename T> void __QuickSort3way(T *arr,int l,int r) { //遞歸的終止條件 if (l>=r) { return; } else { //隨機快速排序選取的隨機值,為了避免在整體大致有序的情況下產生分組不平衡現象,使算法退化 int RAND = (rand() % (r - l) + l); swap(arr[l], arr[RAND]); T v = arr[l]; //小于v的分組的初始索引 int lt = l; //大于v的分組的初始索引 int gt = r + 1; //等于v的分組的初始索引,并且,此索引是數組遍歷值的索引 int i = l + 1; while (i<gt) { //如果遍歷的數據小于v if (arr[i]<v) { //將該數組與第一個等于v的數據交換 swap(arr[lt + 1], arr[i]); //維護小于v的索引和待遍歷的數據的索引 lt++; i++; } //如果數據大于v else if (arr[i]>v) { //交換該數與大于v的第一個數,但是在這里不需要維護i的索引 swap(arr[i], arr[gt - 1]); gt--; } else//arr[i]==v { i++;//直接維護i的索引 } } //最后將數組第一個數v和小于v的最后一個數互換 swap(arr[l],arr[lt]); __QuickSort3way(arr,l,lt); __QuickSort3way(arr,gt,r); } } template <typename T> void QuickSort3way(T *arr,int n) { __QuickSort3way(arr, 0, n - 1); } #endif // !QUICKSORT3_H
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。