日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【算法知识】详解快速排序算法

發(fā)布時(shí)間:2025/3/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【算法知识】详解快速排序算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

基本思想

已發(fā)布:

【算法知識(shí)】詳解選擇冒泡算法

【算法知識(shí)】詳解選擇排序算法

【算法知識(shí)】詳解插入排序算法

本文的思路是以從小到大為例講的。
快速排序的基本思想是任取待排序序列的一個(gè)元素作為中心元素(可以用第一個(gè),最后一個(gè),也可以是中間任何一個(gè)),習(xí)慣將其稱(chēng)為pivot,樞軸元素;
將所有比樞軸元素小的放在其左邊;
將所有比它大的放在其右邊;
形成左右兩個(gè)子表;
然后對(duì)左右兩個(gè)子表再按照前面的算法進(jìn)行排序,直到每個(gè)子表的元素只剩下一個(gè)。

可見(jiàn)快速排序用到了分而治之的思想。
將一個(gè)數(shù)組分成兩個(gè)數(shù)組的方法為:
先從數(shù)組右邊找到一個(gè)比樞軸元素小的元素,將數(shù)組的第一個(gè)位置賦值為該元素;
再?gòu)臄?shù)組的左邊找到一個(gè)比樞軸元素大的元素,將從上面取元素的位置賦值為該值;
依次進(jìn)行,直到左右相遇,把樞軸元素賦值到相遇位置。

例子

輸入數(shù)組
arr 為 [39 , 28 ?, 55 , ?87 , 66 , 3 ,17 ,39*]
為了區(qū)別兩個(gè)相同元素,將最后一個(gè)加上 * ;
初始狀態(tài)如下圖:

初始狀態(tài)

定義一樞軸元素pivot,初始化為第一個(gè)元素的值,即39;
查詢(xún)左邊的元素的變量為left,初始值為第一個(gè)元素的索引,0;
查詢(xún)右邊的元素的變量為right,初始值為第一個(gè)元素的索引,7。
如下圖:

初始化

演示第一輪排序過(guò)程
從右邊開(kāi)始,從右邊找到一個(gè)比樞軸元素小的,如果沒(méi)找到right一直自減1;

第一輪排序狀態(tài)1

然后把當(dāng)前l(fā)eft所在元素賦值為該值;
這里right所指元素并沒(méi)有空,只是為了好演示,設(shè)置為空(下同);

第一輪排序狀態(tài)2

然后從左邊開(kāi)始找一個(gè)比樞軸元素pivot大的元素;如果沒(méi)找到left一直自增1;

第一輪排序狀態(tài)3

將當(dāng)前right所指元素設(shè)為該值;

第一輪排序狀態(tài)4

然后從右邊找到一個(gè)比樞軸元素小的,如果沒(méi)找到right一直自減1;

第一輪排序狀態(tài)5

將當(dāng)前l(fā)eft所指元素設(shè)為該值;

第一輪排序狀態(tài)6

然后從左邊開(kāi)始找一個(gè)比樞軸元素pivot大的元素;如果沒(méi)找到left一直自增1;

第一輪排序狀態(tài)7

將當(dāng)前right所指元素設(shè)為該值;

第一輪排序狀態(tài)8

然后從右邊找到一個(gè)比樞軸元素小的,如果沒(méi)找到right一直自減1;

第一輪排序狀態(tài)9

這時(shí)left和right相遇了,將樞軸元素賦值給當(dāng)前位置。

第一輪排序狀態(tài)10

第一輪排序動(dòng)態(tài)過(guò)程:

第一輪排序動(dòng)態(tài)過(guò)程

然后將數(shù)組分成了

[17,28,3] ?與 ?[66, 87, 55, 39*]兩部分;
再對(duì)這兩部分進(jìn)行上述環(huán)節(jié)即可。
反反復(fù)復(fù),直到只剩下一個(gè)元素。

排序全過(guò)程

排序全過(guò)程

代碼

對(duì)每一個(gè)數(shù)組進(jìn)行分化的代碼如下:
初始化pivot為數(shù)組第一個(gè)元素;
只要left還小于right就進(jìn)行循環(huán);
外層循環(huán)內(nèi)部如下:
先從右邊找一個(gè)比樞軸元素小的元素;
將當(dāng)前l(fā)eft所指元素賦值為找到的元素;
再?gòu)淖筮呎乙粋€(gè)比樞軸元素大的元素;
將當(dāng)前right所指元素賦值為找到的元素;
當(dāng)left和right相等將樞軸元素賦值在此。
最后返回中間元素的索引。

public?static?int?partition(int[]?arr,int?left,int?right){int?pivot?=?arr[left];while(left?<?right){while(left<right?&&?arr[right]?>=?pivot)right--;arr[left]?=?arr[right];while(left?<?right?&&?arr[left]<=?pivot)left++;arr[right]?=?arr[left];}arr[left]?=?pivot;return?left;}

快排代碼:
第一個(gè)是快排的重載,直接傳數(shù)組;
然后調(diào)用另一個(gè)重載函數(shù),傳數(shù)組,left為第一個(gè)元素索引0,right為最后一個(gè)元素索引數(shù)組長(zhǎng)度減去1;
主要介紹傳三個(gè)參數(shù)的快排函數(shù):
定義一個(gè)將來(lái)劃分為兩個(gè)數(shù)組的中間元素的索引;
如果left比right小,進(jìn)行一次劃分,將返回來(lái)的值賦值給middle;
對(duì)left到middle - 1的部分進(jìn)行一次快排(遞歸進(jìn)行);
對(duì)middle + 1到right的部分進(jìn)行一次快排(遞歸進(jìn)行)。

public?static?void?quickSort(int[]?arr){quickSort(arr,0,arr.length-1);System.out.println(Arrays.toString(arr));}public?static?void?quickSort(int[]?arr,int?left,int?right){int?middle;if(left?<?right){middle?=?partition(arr,left,right);quickSort(arr,left,middle-1);quickSort(arr,middle+1,right);}}

完整代碼:

import?java.util.Arrays;public?class?Solution?{public?static?void?main(String[]?args)?{quickSort(new?int[]{39,28,55,87,66,3,17,39});}public?static?void?quickSort(int[]?arr){quickSort(arr,0,arr.length-1);System.out.println(Arrays.toString(arr));}public?static?void?quickSort(int[]?arr,int?left,int?right){int?middle;if(left?<?right){middle?=?partition(arr,left,right);quickSort(arr,left,middle-1);quickSort(arr,middle+1,right);}}public?static?int?partition(int[]?arr,int?left,int?right){int?pivot?=?arr[left];while(left?<?right){while(left<right?&&?arr[right]?>=?pivot)right--;arr[left]?=?arr[right];while(left?<?right?&&?arr[left]<=?pivot)left++;arr[right]?=?arr[left];}arr[left]?=?pivot;return?left;} }

時(shí)間復(fù)雜度

理想的情況:
每次劃分所選擇的中軸元素恰好將當(dāng)前序列幾乎等分,經(jīng)過(guò)趟劃分,便可以排序完畢。這樣,所以理想狀態(tài)下整個(gè)算法的時(shí)間復(fù)雜度為。
最壞的情況是,每次所選的中間數(shù)是當(dāng)前序列中的最值元素,這時(shí)每次劃分的兩個(gè)子表一個(gè)長(zhǎng)度是0,一個(gè)是當(dāng)前數(shù)組長(zhǎng)度減去1。這樣的話(huà),長(zhǎng)度為n的數(shù)組需要經(jīng)過(guò)n趟劃分,這時(shí)的時(shí)間復(fù)雜度為;
為改善最壞情況下的時(shí)間性能,可以在最樞軸元素的原則中進(jìn)行優(yōu)化,選第一個(gè)元素,最后一個(gè)元素,中間元素中的中位數(shù)即可。
這時(shí),快速排序的時(shí)間復(fù)雜度即為。

穩(wěn)定性

如下面的數(shù)組
相同元素用 * ?標(biāo)出 [ 2 , 3 ?, 1, 1* ]
第一次排序?yàn)?br />[1* , 1, 2, 3]
第二次為
[1* , 1 , 2 , 3] 相對(duì)順序發(fā)生了變化,所以是不穩(wěn)定的。

往期精彩回顧適合初學(xué)者入門(mén)人工智能的路線(xiàn)及資料下載機(jī)器學(xué)習(xí)在線(xiàn)手冊(cè)深度學(xué)習(xí)在線(xiàn)手冊(cè)AI基礎(chǔ)下載(pdf更新到25集)本站qq群1003271085,加入微信群請(qǐng)回復(fù)“加群”獲取一折本站知識(shí)星球優(yōu)惠券,復(fù)制鏈接直接打開(kāi):https://t.zsxq.com/yFQV7am喜歡文章,點(diǎn)個(gè)在看

總結(jié)

以上是生活随笔為你收集整理的【算法知识】详解快速排序算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。