快速排序圖解
關(guān)注:92 發(fā)布時間:2021-06-22 12:19:57
之前我們在交換類排序中引入了冒泡排序,這次引入了另一種交換類排序,叫做快速排序。快速排序的優(yōu)點是原地排序,不占用額外空間,時間復(fù)雜度為o(nlogn)。
當(dāng)然對于快速排序也有缺點。對于包含大量重復(fù)元素的數(shù)組排序效率非常低,時間復(fù)雜度會降低到o(n ^ 2)。此時,我們需要使用改進的快速排序-雙向快速排序。在雙向快速排序的基礎(chǔ)上,進一步優(yōu)化了三向快速排序。
快速排序
快速排序的基本思想是通過一遍排序?qū)⒋判虻臄?shù)據(jù)分成兩個獨立的部分,其中一部分的所有數(shù)據(jù)都小于另一部分的所有數(shù)據(jù),然后按照這種方法分別對這兩部分數(shù)據(jù)進行快速排序,整個排序過程可以遞歸進行,使整個數(shù)據(jù)成為有序序列。
快速排序步驟如下:
1.以第一個元素為分界點,用l指向它。
2.遍歷右邊的元素。在遍歷的過程中,我們排列數(shù)組,有的小于v,有的大于v,用j指向小于v和大于v的分界點,用i指向當(dāng)前訪問的元素e,此時數(shù)組arr[l 1…j]v,arr [j 1 … i-1] v。
3.如果ev,直接在大于v的部分后面合并e,然后我繼續(xù)比較下面的元素。
4.如果ev,把e移到j(luò)指向的元素的后面元素,然后j,然后我繼續(xù)比較后面的元素。
5.這樣遍歷整個數(shù)組一次。遍歷后,數(shù)組分為三部分,左邊部分為v,中間部分為v,右邊部分為v。
6.比較后我們把l指向的元素和j指向的元素進行交換,這樣元素v就很快排序了。v的左邊元素小于v,右邊元素大于v。
現(xiàn)在我們用上面的方法快速排序數(shù)組[2,1,4,3,7,8,5,6]。下圖顯示了快速排序的整個過程:
快速排序代碼:
公共靜態(tài)無效排序(可比[] arr) {
int n=arr.length
sort(arr,0,n1);
}
//遞歸使用快速排序?qū)rr的范圍進行排序[l…r]
私有靜態(tài)空排序(可比[] arr,int l,int r) {
if (l=r) {
返回;
}
//分區(qū)arr[l…r]并返回p,這樣arr[l…p-1]arr[p];arr[p 1…r] arr[p]
int p=partition(arr,l,r);
排序(arr,l,p1);
sort(arr,p 1,r);
}
私有靜態(tài)int分區(qū)(可比[] arr,int l,int r) {
//比較左邊的元素用作校準(zhǔn)點
可比v=arr[l];
int j=l;
for(int i=l 1;i=r;i ) {
if (arr[i]。compareto(v) 0)
swap(arr,j 1,i);
j .
}
}
swap(arr,l,j);
返回j;
}
優(yōu)化快速排序
經(jīng)過上面的介紹,我們可以發(fā)現(xiàn)快速排序并不能保證每個分割都有相同大小的子陣,所以可能一邊小一邊大。對于有序數(shù)組,快速排序的時間復(fù)雜度變成o(n ^ 2),相當(dāng)于樹退化成鏈表。下圖顯示了這一變化:
上面,我們使用左邊的第一個元素作為校準(zhǔn)元素。現(xiàn)在我們隨機選擇一個元素作為校準(zhǔn)元素。此時第一次選擇第一個元素的概率為1/n,第二個元素為1/n-1。以此類推,在出現(xiàn)之前退化成鏈表的概率是1/n(n-1)(n-2)…。當(dāng)n較大時,這個概率幾乎為零。
另一個優(yōu)化是對小規(guī)模數(shù)組使用插入排序,因為遞歸會使小規(guī)模問題中的方法調(diào)用過于頻繁,并且插入排序?qū)τ谛∫?guī)模數(shù)組非常快。
優(yōu)化的快速排序代碼:
公共靜態(tài)無效排序(可比[] arr) {
int n=arr.length
sort(arr,0,n1);
}
//賀盛文賀盛文,-什么停止[l.r]阿云阿云阿云阿云阿云阿云阿云
私有靜態(tài)void排序(相當(dāng)于[] arr,int l,int r)}
//云娥與云娥,云娥與云娥
如果(rl=15)}
insertonstart。sort(arr、l、r);
返回;
}
//-什么停止[l.r]阿悅分割區(qū)誒誒喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲喲,阿忠p,你知道嗎?僧兒頁:1:停止[p1.r]停止[p]
int p=分區(qū)(arr、l、r);
輸出(arr,l,p-1);
(經(jīng)常預(yù)算):
}
專用靜態(tài)(同internationalorganizations)國際組織部件
(可比[] arr,int l,int r) {
//在arr[l…r]范圍內(nèi)隨機選擇一個值作為校準(zhǔn)點軸心
swap(arr,l,(int)(math . random*(rl ^ 1))l);
可比v=arr[l];
int j=l;
for(int i=l 1;i=r;i ) {
if (arr[i]。compareto(v) 0)
swap(arr,j 1,i);
j .
}
}
swap(arr,l,j);
返回j;
}
雙向快速排序
對于包含大量重復(fù)元素的數(shù)組,上面的快速排序效率很低,因為在我們上面的判斷中,如果元素小于v,那么元素就放在v部分,如果元素大于等于v,那么就放在v部分。這時如果數(shù)組中有大量重復(fù)的元素,v部分會變得很長,導(dǎo)致左右兩邊不平衡,性能降低。
雙向快速排序的步驟如下:
1.把v和v放在數(shù)組的兩端,用i指向v的下一個元素,用j指向v的前一個元素。
2.從i向后遍歷,如果遍歷的元素ev繼續(xù)向后遍歷,直到遍歷的元素e=v,那么停止遍歷。從j開始向前遍歷,如果遍歷的元素為ev,繼續(xù)向前遍歷,直到遍歷的元素e=v,然后停止遍歷。
3.交換一下我指向的元素和j指向的元素,然后我,j繼續(xù)比較下一個。
雙向快速排序代碼:
公共靜態(tài)無效排序(可比[] arr) {
int n=arr.length
sort(arr,0,n1);
}
私有靜態(tài)空排序(可比[] arr,int l,int r) {
//對于小規(guī)模數(shù)組,使用插入排序
if(rl=15){
insertionsort.sort(arr,l,r);
返回;
}
int p=partition(arr,l,r);
排序(arr,l,p1);
sort(arr,p 1,r);
}
私有靜態(tài)int分區(qū)(可比[] arr,int l,int r) {
//在arr[l…r]范圍內(nèi)隨機選擇一個值作為校準(zhǔn)點軸心
swap(arr,l,(int)(math . random*(rl ^ 1))l);
可比v=arr[l];
int i=l 1,j=r;
while (true) {
//注意這里的邊界,arr[i]。compareto(v) 0,不能是arr[i]。compareto(v)=0
//如果不加等號,此時會退出while循環(huán),也就是交換i和j的值,這樣對于一個包含大量相同元素的數(shù)組,交換兩邊相等的數(shù)據(jù),可以在一定程度上保證兩路的數(shù)據(jù)平衡。
//從i向后遍歷,如果遍歷的元素ev,繼續(xù)向后遍歷,直到遍歷的元素e=v,然后停止遍歷
while (i=r arr[i]。compareto(v) 0)
i;
}
//從j開始向前遍歷,如果遍歷的元素為ev,繼續(xù)向前遍歷,直到遍歷的元素e=v,然后停止遍歷
while(j=l ^ 1 arr[j]。compareto(v) 0)
j ;
}
if (i=j) {
打破;
}
swap(arr,i,j);
i;
j ;
}
//此時j指向的元素是數(shù)組中小于v的比較后一個元素,i指向的元素是數(shù)組中大于v的第一個元素。
swap(arr,l,j);
返回j;
}
三向快速排序
三向快速排序的步驟如下:
1.在雙向快速排序的基礎(chǔ)上,我們將等于v的元素作為單一部分。lt指向小于v部分的比較后一個元素,gt指向大于v部分的第一個元素。
2.從i向后遍歷,如果遍歷的元素e=v,e直接合并到=v部分,然后i繼續(xù)遍歷。如果你遍歷元素ev,交換e部分的第一個元素和=v(lt 1指向的元素),然后lt,我繼續(xù)遍歷。如果遍歷的元素ev,則交換e和v的前一個元素(gt-1指向的元素),然后gt ,但此時不需要改變i,因為i位置的元素與gt位置之前的空白元素交換。
3.遍歷之后,i=gt,然后用lt-pointing元素交換l-pointing元素。
4.在v形零件和v形零件上執(zhí)行上述操作。
三向快速排序相對于雙向快速排序的優(yōu)勢在于,減少了重復(fù)元素的比較操作,因為重復(fù)元素在一次排序中已經(jīng)被排列為單一部分,然后只需要對不等于重復(fù)元素的其他元素進行排序。
三向快速排序代碼:
公共靜態(tài)無效排序(可比[] arr) {
int n=arr.length
sort(arr,0,n1);
}
私有靜態(tài)空排序(可比[] arr,int l,int r) {
//對于小規(guī)模數(shù)組,使用插入排序
if(rl=15){
insertionsort.sort(arr,l,r);
返回;
}
//在arr[l…r]范圍內(nèi)隨機選擇一個值作為校準(zhǔn)點軸心
swap(arr,l,(int)(math . random*(rl ^ 1))l);
可比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]。compareto(v) 0)
swap(arr,i,lt 1);
i;
lt。
} else if (arr[i]。compareto(v) 0)
互換(arr,i,gt1);
gt ;
} else { //arr[i]==v
i;
}
}
互換(arr,l,lt);
排序(arr,l,lt1);
sort(arr,gt,r);
}
摘要
本文介紹了快速排序、快速排序的優(yōu)化、雙向快速排序和三向快速排序。
為了快速排序,我們需要選擇合適的校準(zhǔn)點,使校準(zhǔn)點的兩側(cè)平衡;當(dāng)在快速排序中遞歸到小數(shù)組時,我們可以用插入排序來代替遞歸,以減少不必要的開銷。
對于雙向快速排序和三向快速排序,我們在數(shù)組中使用了大量重復(fù)的元素。
比較后,建議jdk底部的排序使用插入排序 雙路快速排序
合并和排序的組合。
上一篇:平安專享額度怎么用?
猜你喜歡
-
過去十年見證了中國經(jīng)濟的巨大變化。從2009年開始,經(jīng)濟學(xué)家開始預(yù)測,明年將是中國經(jīng)濟發(fā)展最困難的一年。隨著移動互聯(lián)網(wǎng)的逐漸普及,人們的生活方式發(fā)生了巨大的變化。與此同時…
-
華為手機安全模式怎么解除73人支持
手機安全模式是手機系統(tǒng)中的一種特殊模式,其原理類似于windows安全模式。手機的安全模式只加載系統(tǒng)的基本功能和一些預(yù)設(shè)的應(yīng)用,其他用戶安裝的第三方應(yīng)用無法在安全模式下顯…
-
木三事件是怎么回事77人支持
網(wǎng)上有很多匪夷所思的靈異事件,有些是網(wǎng)友的親身經(jīng)歷,有些沒有得到證實,但被網(wǎng)友的口碑渲染得有點嚇人。三目事件和當(dāng)年的左陽事件類似,但是后來她沒有再出現(xiàn)在網(wǎng)絡(luò)上,大家都很擔(dān)…
-
美柚和大姨嗎哪個好用?87人支持
市面上誕生了很多女性健康管理app,但最終deus ex和美柚占據(jù)了主要市場份額。未來女性健康管理領(lǐng)域的“霸主”是誰?是“吞并”還是“共存”?目前似乎沒有定論。初期社區(qū)戰(zhàn):美柚…
-
工勤崗位是什么意思112人支持
事業(yè)單位分為管理崗位、專業(yè)技術(shù)崗位和工業(yè)后勤崗位。管理崗位和專業(yè)技術(shù)崗位是干部,工業(yè)和后勤崗位是工人。所有政府機關(guān)和事業(yè)單位都要求每個報名的人都必須參加考試。所以…
-
目前筆記本電腦哪款好93人支持
題主沒有給出買電腦的目的和預(yù)算,只能說說個人經(jīng)歷。因為是工作需要,主要用于辦公需要,所以我現(xiàn)在用的是聯(lián)想thinkpad x1 carbon(不是廣告,這個型號我用了好幾年了),也推薦這個…
-
注冊tik tok賬戶時,開發(fā)者許可協(xié)議中明確規(guī)定,當(dāng)您發(fā)布視頻時,默認情況下,每個人都可以在未經(jīng)您授權(quán)的情況下轉(zhuǎn)載和使用它。盡量有辦法。您可以在視頻中添加水印。例如:“未經(jīng)授…
-
在別人眼里的“43人支持
之前認識一個合伙人,月薪八萬多,設(shè)計圖紙做的挺好。我給她的工作都是可以熟練完成的,每次完成的時間超出了我的想象。有一次請她吃飯,發(fā)現(xiàn)她在幾個平臺上盈利,而且是在工作之外做…
-
k40系列怎么樣31人支持
今天在小米之家體驗了紅米在線發(fā)布的最新k40系列,想說一下對你的一些感受。1.外貌方面,個人感覺幻境最好,其次是晴天和下雪天,最后是明亮和黑暗。幻想那個顏色真好看,角度不一樣,…
-
電話催收是爛工作嗎56人支持
還有其他網(wǎng)點或者其他工作,建議大家不要打電話催收。第一,人性的惡會在工作中被無限放大;第二,這條線的水靠電很深,賺了辛苦錢上岸可能不安全。有可能嘗試收銀行違約,但是很多電催…
-
淘寶網(wǎng)新手開店入門4人支持
一、注冊賬號首先,第一步一定要注冊淘寶賬號。這里按照注冊的基本操作,相信大家都能完成。但是,不能修改旺旺的名稱。在確定要做什么品類之后,旺旺的名字要和店鋪、產(chǎn)品、品類相…
-
天貓網(wǎng)店開店費用65人支持
開一家天貓旗艦店,也就是天貓最高級的店,首先要滿足天貓入駐的條件!假設(shè)你能達到天貓的入門要求,那么基本成本是多少?你可以算一下:1.天貓押金10萬!2.技術(shù)服務(wù)費3萬元!3.質(zhì)檢費用100…
熱門十大品牌
- 2021年我國十大黃金品牌排行榜30998人
- 眼鏡品牌十大排行榜前10名26345人
- 十大證券公司排行榜前10名23241人
- 2021年我國雜志排行榜前10名20053人
- 我國十大雜志排行榜前10名16355人
- 2021我國十個宜居城市排行榜前11485人
- 男士褲子品牌十大排行榜前10名11185人
- 2021十大火熱電腦游戲排行榜前11056人
- 十大衛(wèi)生巾品牌排行榜前十名8846人
- 我國十大襪子品牌排行榜前十名8364人