據(jù)說快速排序算法是實(shí)際當(dāng)中最常用的一種排序算法,是冒泡排序的一種改進(jìn),速度快,效率高。于是我查了一下百科,然后按照自己的思路給實(shí)現(xiàn)了一下。
快速排序的百科
基本思想:通過一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)比另外一部分的所有數(shù)據(jù)都要小。然后按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序。整個(gè)排序過程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。
理解:其實(shí)他的基本思想就是在要排序的數(shù)中隨便取一個(gè)數(shù)(既然是隨便,那就不如取第一個(gè))為參考數(shù),通過排序,以參考數(shù)為中心,使小于參考數(shù)的都在左邊,大于的在右邊,至于等于參考數(shù)的我理解沒有必要特意移動(dòng)他的位置了,哪里都一樣,反正跟參考數(shù)相等。之后再遞歸參考數(shù)左右兩邊的數(shù)據(jù)。
一次快速排序的過程:
(1)取數(shù)組第一個(gè)數(shù)作為參考數(shù)key;
(2)設(shè)置坐標(biāo)值i為0,j為數(shù)組count-1;
(3)從j開始向前搜索,當(dāng)遇到第一個(gè)比key小的值的時(shí)候,將坐標(biāo)為j的數(shù)據(jù)與坐標(biāo)為i的數(shù)據(jù)進(jìn)行交換;
(4)從i開始向后搜索,當(dāng)遇到第一個(gè)比key大的值的時(shí)候,將坐標(biāo)為i的數(shù)據(jù)與坐標(biāo)為j的數(shù)據(jù)進(jìn)行交換;
(5)重復(fù)(3)和(4),直到i>=j,停止搜索,此時(shí)的數(shù)據(jù)則是以key為參考值,key左邊的數(shù)據(jù)都小于等于key,右邊的都大于等于key。
圖示舉例:
初始狀態(tài):
i = 0, j = 10, key = 12
第一次查詢替換,從右向左 ? ?
i = 0, j = 8, key = 12
第二次查詢替換,從左向右 ?
i = 1, j = 8, key = 12
第三次查詢替換,從右向左,從上圖可以看出,12的右邊已經(jīng)沒有比12小的數(shù)了,所以依次搜索到j(luò) = 1 = i后,搜索停止。此時(shí)就已經(jīng)完成了第一輪的快速排序。
完整的快速排序:
完成一輪的排序之后,已經(jīng)將數(shù)據(jù)以key值為中心分成了左右小大數(shù)兩派了,接下來就是遞歸這兩派就好了,一般都不會(huì)采取將數(shù)據(jù)直接截開然后再拼接的做法,而是將需要遞歸的范圍傳入到方法當(dāng)中,比如第一輪的排序是從0到count-1,那么第二輪就應(yīng)該是從0到i,從j + 1到count-1。
注意,這里有一個(gè)坑!!!之前我的理解是,第二輪的排序從j + 1到count - 1和從j到count - 1是一樣的,區(qū)別只是把參考值再重新排一遍。但是這是不對(duì)的,一定要注意這里,否則容易出現(xiàn)死循環(huán)。對(duì)于一個(gè)第一個(gè)數(shù)是最小數(shù)的數(shù)組,那么第一輪排序時(shí)是從0到count-1,排序過后的關(guān)鍵值是i=0,j=0,那么如果第二次排序的時(shí)候是按照j到count-1,則依然是0到count-1。所以,如果是選擇第一個(gè)數(shù)據(jù)為參考數(shù),那么第二次排序的時(shí)候一定是j+1到count-1,0到i(或者是0到i - 1,這個(gè)無所謂,因?yàn)椴粫?huì)出現(xiàn)上述情況)。同理,如果喜歡以最后一個(gè)數(shù)據(jù)作為參考數(shù)的話,那么第二段排序的分段則是從0到i - 1,j到count-1(或者j+1到count - 1)。
接下來為OC的關(guān)鍵代碼:
快排的大致原理就是這樣,測試的時(shí)候一定記得測試特殊情況:
(1)取第一個(gè)數(shù)為參考數(shù),第一數(shù)即為最小或者最大數(shù)。
(2)取最后一個(gè)數(shù)為參考數(shù),最后一個(gè)數(shù)即為最大或者最小數(shù)。