回顧快排

快速排序,面試必問題。面試百度時(shí)三次面試被問到快排,本以為掌握的很好,但細(xì)節(jié)方面還是不到位,發(fā)揮的不是很好,特此記錄,勉勵(lì)自己。

問題:為什么是nlog(n),n怎么來(lái),log(n)怎么來(lái)

快速排序
快速排序是應(yīng)用最廣泛的排序算法,基本思路是:將一個(gè)數(shù)組分成兩個(gè)子數(shù)組,將兩部分獨(dú)立排序,當(dāng)兩個(gè)子數(shù)組都有序時(shí),整個(gè)數(shù)組也就有序了,這與歸并排序有所不同,歸并排序中,將一個(gè)數(shù)組分成兩個(gè)數(shù)組后,需要對(duì)兩個(gè)子數(shù)組進(jìn)行歸并,在歸并的過(guò)程中排序,而快速排序是在將一個(gè)數(shù)組分成兩個(gè)數(shù)組的過(guò)程中進(jìn)行排序,當(dāng)分到盡頭的時(shí)候,數(shù)組就已經(jīng)有序了,不需要再進(jìn)行其它任何操作
快速排序中重點(diǎn)是找到將一個(gè)數(shù)組分為兩個(gè)數(shù)組的切分點(diǎn),在歸并排序中,其實(shí)也是有這樣的切分點(diǎn)的,就是 mid,也就是說(shuō)歸并排序默認(rèn)將一個(gè)數(shù)組等分,而在快速排序中,對(duì)一個(gè)數(shù)組的切分,并不一定是等分,需要根據(jù)具體的切分點(diǎn)的位置來(lái)進(jìn)行切分,所以,找到合適的切分點(diǎn)的位置是很重要的,直接影響到整個(gè)排序的性能。
尋找切分點(diǎn)
切分點(diǎn)需要滿足三個(gè)條件:(假設(shè)切分點(diǎn)索引為 k)
對(duì)于某個(gè)索引 k,數(shù)組中對(duì)應(yīng)索引的值 a[k] 是確定的
數(shù)組索引[lo,k-1] (即切分點(diǎn)左邊的所有元素) 中的所有元素的值都不大于切分點(diǎn)元素的值( <= )
數(shù)組索引[k+1,hi] (即切分點(diǎn)右邊的所有元素) 中的所有元素的值都不小于切分點(diǎn)元素的值( >= )

假設(shè)有一組數(shù):


尋找切分點(diǎn)的過(guò)程是:(其中 lo 為數(shù)組最低位索引,hi 為數(shù)組最高位索引,從左往右遍歷的指針為 i,從右往左遍歷的指針為 j)
取 a[lo] 的值作為初始切分點(diǎn)元素的值,即切分點(diǎn)索引為 0,值為 16

從數(shù)組左端向右遍歷[1,5],當(dāng)遇到一個(gè)大于等于切分點(diǎn)的元素,即索引為 2 的元素,停止遍歷,此時(shí) i=2

從數(shù)組右端向左遍歷[5,0],當(dāng)遇到一個(gè)小于等于切分點(diǎn)的元素,即索引為 5 的元素,停止遍歷,此時(shí) j=5

交換 i 和 j 對(duì)應(yīng)的值,交換后:


從數(shù)組左端向右遍歷[3,5],當(dāng)遇到一個(gè)大于等于切分點(diǎn)的元素,即索引為 5 的元素,停止遍歷,此時(shí) i=5

從數(shù)組右端向左遍歷[4,0],當(dāng)遇到一個(gè)小于等于切分點(diǎn)的元素,即索引為 4 的元素,停止遍歷,此時(shí) j=4

當(dāng) i>=j 時(shí)停止循環(huán),不會(huì)執(zhí)行 i 和 j 的交換,而是將切分點(diǎn)元素和 j 元素交換,交換后:

到此,尋找第一個(gè)切分點(diǎn)完成,切分點(diǎn)索引為 4,對(duì)應(yīng)的值為 16
找到切分點(diǎn),接下來(lái)將數(shù)組按照切分點(diǎn)分成兩部分,從上面的執(zhí)行結(jié)果可以知道,數(shù)組將被分為 [0,3] 和 [5,5],接下來(lái)就是對(duì) [0,3] 部分重復(fù)尋找切分點(diǎn)的過(guò)程:
取 a[lo] 的值作為初始切分點(diǎn)元素的值,即切分點(diǎn)索引為 0,值為 14


從數(shù)組左端向右遍歷[1,3],當(dāng)遇到一個(gè)大于等于切分點(diǎn)的元素,沒有找到,遍歷到數(shù)組盡頭,此時(shí) i=3

從數(shù)組右端向左遍歷[3,0],當(dāng)遇到一個(gè)小于等于切分點(diǎn)的元素,即索引為 3 的元素,停止遍歷,此時(shí) j=3

當(dāng) i>=j 時(shí)停止循環(huán),不會(huì)執(zhí)行 i 和 j 的交換,而是將切分點(diǎn)元素和 j 元素交換,交換后:

到此,尋找第二個(gè)切分點(diǎn)完成,切分點(diǎn)索引為 3,對(duì)應(yīng)的值為 14

同理,數(shù)組將按照切分點(diǎn)分為 [0,2] 和[3,3],接下來(lái)對(duì) [0,2] 部分重復(fù)尋找切分點(diǎn):
取 a[lo] 的值作為初始切分點(diǎn)元素的值,即切分點(diǎn)索引為 0,值為 11


從數(shù)組左端向右遍歷[1,2],當(dāng)遇到一個(gè)大于等于切分點(diǎn)的元素,即索引為 1 的元素,停止遍歷,此時(shí) i=1

從數(shù)組右端向左遍歷[2,0],當(dāng)遇到一個(gè)小于等于切分點(diǎn)的元素,沒有找到,遍歷到數(shù)組起始位置,此時(shí) j=0

當(dāng) i>=j 時(shí)停止循環(huán),不會(huì)執(zhí)行 i 和 j 的交換,而是將切分點(diǎn)元素和 j 元素交換,交換后:

到此,尋找第三個(gè)切分點(diǎn)完成,切分點(diǎn)索引為 0,對(duì)應(yīng)的值為 11
此時(shí),由于切分點(diǎn)位置為 0,所以只能切分出一個(gè)子數(shù)組,即 [1,2],繼續(xù)尋找切分點(diǎn)
取 a[lo] 的值作為初始切分點(diǎn)元素的值,即切分點(diǎn)索引為 1,值為 13


從數(shù)組左端向右遍歷[2,2],當(dāng)遇到一個(gè)大于等于切分點(diǎn)的元素,沒有找到,遍歷到數(shù)組盡頭,此時(shí) i=2

從數(shù)組右端向左遍歷[2,1],當(dāng)遇到一個(gè)小于等于切分點(diǎn)的元素,即索引為 2 的元素,此時(shí) j=2

當(dāng) i>=j 時(shí)停止循環(huán),不會(huì)執(zhí)行 i 和 j 的交換,而是將切分點(diǎn)元素和 j 元素交換,交換后:

到此,尋找第四個(gè)切分點(diǎn)完成,切分點(diǎn)索引為 2,對(duì)應(yīng)的值為 12
數(shù)據(jù)已經(jīng)有序了,整個(gè)過(guò)程中尋找了四次切分點(diǎn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,644評(píng)論 18 399
  • 最近在讀< >時(shí),了解到了很多常用的排序算法,故寫一篇讀書筆記記錄下這些排序算法的思路和實(shí)現(xiàn). 冒泡排序 冒泡排序...
    SylvanasSun閱讀 808評(píng)論 0 0
  • 某次二面時(shí),面試官問起Js排序問題,吾絞盡腦汁回答了幾種,深感算法有很大的問題,所以總計(jì)一下! 排序算法說(shuō)明 (1...
    流浪的先知閱讀 1,252評(píng)論 0 4
  • 什么是產(chǎn)品經(jīng)理 產(chǎn)品經(jīng)理(Product Manager)就是企業(yè)中專門負(fù)責(zé)產(chǎn)品管理的職位,產(chǎn)品經(jīng)理負(fù)責(zé)調(diào)查并根據(jù)...
    牧星銀河閱讀 2,089評(píng)論 0 9
  • 萬(wàn)事開頭難,興致滿滿的準(zhǔn)備開始我的第一篇自我討伐,卻發(fā)現(xiàn)好像還是無(wú)從下手?;蛟S還是想給自己留一點(diǎn)的臉面,不至于未來(lái)...
    ythyth8閱讀 370評(píng)論 0 0

友情鏈接更多精彩內(nèi)容