快速排序的三種分區方法


轉載:https://blog.csdn.net/RUIRUI14/article/details/104304341

快速排序–三種實現方式:

快速排序運用了分治思想
  ① 分解:將數組arr[ l…r ]划分為兩個子數組arr[ l…p-1 ]和arr[ p+1…r ]。使得arr[ p ]為大小居中的數,即左側arr[ l…p-1 ]中的每個元素都小於等於它;而右側arr[ p+1…r ]中的每個元素都大於等於它。其中計算下標p也是划分過程的一部分。
  ② 解決:通過遞歸調用快速排序,對子數組arr[ l…p-1 ]和arr[ p+1…r ]進行排序。
  ③ 合並:因為子數組都是原址排序的,所以不需要合並。即A[ l…r ]已經有序。

快排的重點在於划分區域:將小於中間值的元素全放在左邊,大於中間值的元素放在右邊

本文列出了三種快速排序的方法:
  ① 單向掃描分區法
  ② 雙向掃描分區法
  ③ 三指針掃描分區法

方式一:單向掃描分區法

分區方法:
int single_Portion(int[] arr, int l, int r)
  ① 定義數組第一個元素為主元
  ② 定義左指針指向數組第二個元素,右指針指向數組最后一個元素(最終目的是使左指針左側都是小於等於主元的元素,右指針右側都是大於主元的元素)
  ③ 判斷左指針所指元素是否小於等於主元
1.若小於等於主元:左指針右移一位
2.若大於主元:將左指針所指元素與右指針所指元素交換位置,且右指針左移一位
  ④ 直到左指針超過右指針,此時左指針指向大於主元的第一個元素,右指針指向小於等於主元的最后一個元素
  ⑤ 將主元與右指針所指元素交換位置,此時即分區完畢,形成主元左側元素小於等於主元,主元右側元素大於主元

快速排序方法(遞歸實現):
void single_QuickSort(int[] arr, int l, int r)
  ① 調用分區方法Portion(),獲取主元位置
  ② 將主元左側與右側分別進行快速排序,即實現了數組的排序

圖解:

方式二:雙向掃描分區法

分區方法概述(大部分與單向掃描法類似,不再贅述):
int double_Portion(int[] arr, int l, int r)
  ① 與單向掃描分區法大體類似,區別在於:雙向掃描分區法的左指針與右指針同時掃描
  ② 左指針往右掃描,直到遇到第一個大於主元的元素停下;右指針往左掃描,知道遇到第一個小於等於主元的元素停下
  ③ 將兩指針所指元素交換位置后,兩指針繼續掃描重復②

快速排序函數:與單向掃描分區法相同
void double_QuickSort(int[] arr, int l, int r)

圖解:

方式三:三指針分區法

分區方法概述:
int[] tri_Portion(int[] arr, int l, int r)
  ① 如果數組中存在很多與主元等值的元素,那么在對主元左、右側進行快速排序時,可以不用對那些與主元等值的元素進行排序
  ② 增設一個等值指針,來標記第一個與主元相等的元素,最終將區域划分為三部分:
1.左側為所有小於主元的元素
2.中間為所有等於主元的元素
3.右側為所有大於主元的元素

快速排序方法概述:
void tri_QuickSort(int[] arr, int l, int r)
  ① 將第一個等於主元的元素的左側進行快排,將最后一個等於主元的元素的右側進行快排

圖解:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM