快速排序知識(shí)梳理(老三帶你學(xué))
眾所周知啊,快速排序是一種常用的排序算法,其基本思路是先選擇一個(gè)基準(zhǔn)值,然后通過將小于基準(zhǔn)值的元素移到前面,大于基準(zhǔn)值的元素移到后面,由此就將一個(gè)數(shù)組變成了兩個(gè)有序子數(shù)組。之后對(duì)于子數(shù)組再次進(jìn)行上述操作,直到子數(shù)組長(zhǎng)度為1,就是全部有序了。這次,我們將逐步介紹快速排序中產(chǎn)生各個(gè)概念及實(shí)現(xiàn)方式,幫助大家掌握這一重要的排序算法。
1.遞歸
上面描述中,對(duì)于子數(shù)組重復(fù)進(jìn)行分割操作直到全部有序,就是一種遞歸操作。遞歸是快速排序的核心算法,它通過將問題分而治之的思想,將一個(gè)大問題分解成多個(gè)小問題,并對(duì)這些小問題再進(jìn)行遞歸處理。在遞歸中,為了避免無限遞歸,我們需要明確遞歸的退出條件和遞進(jìn)條件。
可以看到,上述程序中,遞歸退出條件是n==0,而遞進(jìn)條件是n!=0。
在遞歸過程中,我們使用調(diào)用棧這種數(shù)據(jù)結(jié)構(gòu)來記錄每個(gè)遞歸函數(shù)的狀態(tài),并按照先進(jìn)后出的順序進(jìn)行處理。
2.分區(qū)
快速排序中的分區(qū)操作是將數(shù)組分為小于基準(zhǔn)值和大于基準(zhǔn)值的兩個(gè)部分,以保證基準(zhǔn)值的位置是有序的。
我們常用的有兩種分區(qū)方式:Lomuto分區(qū)和Hoare分區(qū)。
Lomuto分區(qū):雙指針同向
Lomuto分區(qū)中,我們將右指針指向數(shù)組最后一個(gè)元素,左指針指向數(shù)組第一個(gè)元素,然后從左到右遍歷數(shù)組,若當(dāng)前元素小于基準(zhǔn)值,則將其與右指針指向的元素交換,并將右指針左移一位,最終將基準(zhǔn)值放到右指針的位置上,分區(qū)完成。
Hoare分區(qū):雙指針反向
Hoare分區(qū)中,我們將左指針指向數(shù)組第一個(gè)元素,右指針指向數(shù)組最后一個(gè)元素,然后從兩邊同時(shí)開始遍歷數(shù)組,若左指針指向元素大于基準(zhǔn)值且右指針指向元素小于基準(zhǔn)值,則交換這兩個(gè)元素,繼續(xù)遍歷。當(dāng)左指針和右指針相遇時(shí),將基準(zhǔn)值與相遇位置的元素交換,分區(qū)完成。
3.排序
在分區(qū)完成后,我們可以利用遞歸的方式對(duì)小于和大于基準(zhǔn)值的子數(shù)組進(jìn)行排序。此時(shí),遞歸的退出條件是當(dāng)子數(shù)組長(zhǎng)度為0或1時(shí),即表示當(dāng)前子數(shù)組已經(jīng)有序。而遞進(jìn)條件則是在分區(qū)過程中,將小于基準(zhǔn)值的元素移到前面,大于基準(zhǔn)值的元素移到后面,并繼續(xù)遞歸處理子數(shù)組。
4.優(yōu)化
在實(shí)現(xiàn)快速排序時(shí),我們可以考慮一些優(yōu)化措施,以提高算法的效率和減少排序時(shí)間。比如,對(duì)于基準(zhǔn)值的選擇,我們可以采用隨機(jī)選取或三數(shù)取中的方式,以防止出現(xiàn)最壞情況;對(duì)于長(zhǎng)度比較小的子數(shù)組,我們可以使用插入排序代替遞歸;對(duì)于分區(qū)過程中基準(zhǔn)值相同的情況,我們可以采用等于基準(zhǔn)值的方法分區(qū),以提高效率。
5.快速選擇
快速選擇是快速排序的另一種應(yīng)用場(chǎng)景,它可以在無序數(shù)組中快速找到第k小的元素??焖龠x擇的實(shí)現(xiàn)原理與快速排序類似,同樣采用遞歸的方式分治處理。在每次分區(qū)時(shí),我們可以根據(jù)基準(zhǔn)值的位置與k的關(guān)系,選擇只在小于基準(zhǔn)值的子數(shù)組中遞歸處理,或者只在大于基準(zhǔn)值的子數(shù)組中遞歸處理。
總結(jié)
綜上所述,快速排序是一種常用且高效的排序算法,它通過遞歸分治的方式將復(fù)雜的問題分解成小問題,并通過分區(qū)逐漸縮小問題規(guī)模。在實(shí)現(xiàn)時(shí),我們需要注意遞歸的退出條件和遞進(jìn)條件,以及選擇分區(qū)方法和優(yōu)化方案,以提高算法的效率和減少排序時(shí)間。