快速排序-三種及雙軸快速排序


主要是雙軸快速排序,其余再最下面的鏈接中

        雙軸快速排序算法思路和三向切分快速排序算法的思路基本一致,雙軸快速排序算法使用兩個軸,通常選取最左邊的元素作為pivot1和最右邊的元素作pivot2。首先要比較這兩個軸的大小,如果pivot1 > pivot2,則交換最左邊的元素和最右邊的元素,已保證pivot1 <= pivot2。雙軸快速排序同樣使用i,j,k三個變量將數組分成四部分

image

 

A[L+1, i]是小於pivot1的部分,A[i+1, k-1]是大於等於pivot1且小於等於pivot2的部分,A[j, R]是大於pivot2的部分,而A[k, j-1]是未知部分。和三向切分的快速排序算法一樣,初始化i = L,k = L+1,j=R,k自左向右掃描直到k與j相交為止(k == j)。我們掃描的目的就是逐個減少未知元素,並將每個元素按照和pivot1和pivot2的大小關系放到不同的區間上去。

在k的掃描過程中我們可以對a[k]分為三種情況討論(注意我們始終保持最左邊和最右邊的元素,即雙軸,不發生交換)

(1)a[k] < pivot1 i先自增,交換a[i]和a[k],k自增1,k接着繼續掃描

(2)a[k] >= pivot1 && a[k] <= pivot2 k自增1,k接着繼續掃描

(3)a[k] > pivot2: 這個時候顯然a[k]應該放到最右端大於pivot2的部分。但此時,我們不能直接將a[k]與j的下一個位置a[--j]交換(可以認為A[j]與pivot1和pivot2的大小關系在上一次j自右向左的掃描過程中就已經確定了,這樣做主要是j首次掃描時避免pivot2參與其中),因為目前a[--j]和pivot1以及pivot2的關系未知,所以我們這個時候應該從j的下一個位置(--j)自右向左掃描。而a[--j]與pivot1和pivot2的關系可以繼續分為三種情況討論

       3.1)a[--j] > pivot2 j接着繼續掃描

       3.2)a[--j] >= pivot1且a[j] <= pivot2 交換a[k]和a[j],k自增1,k繼續掃描(注意此時j的掃描就結束了)

       3.3) a[--j] < pivot1 先將i自增1,此時我們注意到a[j] < pivot1,  a[k] > pivot2,  pivot1 <= a[i] <=pivot2,那么我們只需要將a[j]放到a[i]上,a[k]放到a[j]上,而a[i]放到a[k]上。k自增1,然后k繼續掃描(此時j的掃描就結束了)

注意

1. pivot1和pivot2在始終不參與k,j掃描過程。

2. 掃描結束時,A[i]表示了小於pivot1部分的最后一個元素,A[j]表示了大於pivot2的第一個元素,這時我們只需要交換pivot1(即A[L])和A[i],交換pivot2(即A[R])與A[j],同時我們可以確定A[i]和A[j]所在的位置在后續的排序過程中不會發生變化(這一步非常重要,否則可能引起無限遞歸導致的棧溢出),最后我們只需要對A[L, i-1],A[i+1, j-1],A[j+1, R]這三個部分繼續遞歸上述操作即可。

 

image

鏈接地址:

原文:https://www.cnblogs.com/nullzx/p/5880191.html 

雙軸源碼:https://www.jianshu.com/p/6d26d525bb96


免責聲明!

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



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