快排算法-OC實(shí)現(xiàn)

  • 引自百度百科

快速排序由C. A. R. Hoare在1962年提出跋选。它的基本思想是:通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小秽梅,然后再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個(gè)排序過(guò)程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列研铆。

  • 算法介紹

設(shè)要排序的數(shù)組是Array[0]……Array[N-1]比勉,首先任意選取一個(gè)數(shù)據(jù)(通常選用數(shù)組的第一個(gè)數(shù))作為關(guān)鍵數(shù)據(jù)猾骡,然后將所有比它小的數(shù)都放到它前面,所有比它大的數(shù)都放到它后面敷搪,這個(gè)過(guò)程稱為一趟快速排序兴想。值得注意的是,快速排序不是一種穩(wěn)定的排序算法赡勘,也就是說(shuō)嫂便,多個(gè)相同的值的相對(duì)位置也許會(huì)在算法結(jié)束時(shí)產(chǎn)生變動(dòng)。
一趟快速排序的步驟:
1)設(shè)置兩個(gè)變量i闸与、j,排序開始的時(shí)候:i=0践樱,j=N-1;
2)以第一個(gè)數(shù)組元素作為關(guān)鍵數(shù)據(jù)袱院,賦值給key,即key=Array[0];
3)從j開始向前搜索忽洛,即由后開始向前搜索(j--)腻惠,找到第一個(gè)小于等于key的值A(chǔ)rray[j]欲虚,將Array[j]的值賦給Array[i];
4)從i開始向后搜索复哆,即由前開始向后搜索(i++)欣喧,找到第一個(gè)大于等于key的Array[i],將Array[i]的值賦給Array[j]梯找;
5)重復(fù)第3、4步初肉,直到i=j; (3,4步中臼隔,沒找到符合條件的值妄壶,即3中A[j]不小于key,4中A[i]不大于key的時(shí)候改變j、i的值丁寄,使得j=j-1,i=i+1伊磺,直至找到為止屑埋。找到符合條件的值,進(jìn)行交換的時(shí)候i摘能, j指針位置不變。另外严望,i==j這一過(guò)程一定正好是i+或j-完成的時(shí)候逻恐,此時(shí)令循環(huán)結(jié)束)峻黍。

過(guò)程演示

下標(biāo) 0 1 2 3 4 5
數(shù)據(jù) 6 2 7 3 8 9

i=0, j=5, k=6
創(chuàng)建變量i=0(指向第一個(gè)數(shù)據(jù)), j=5(指向最后一個(gè)數(shù)據(jù)), k=6(賦值為第一個(gè)數(shù)據(jù)的值)奸披。
我們要把所有比k小的數(shù)移動(dòng)到k的左面涮雷,所以我們可以開始尋找比6小的數(shù)轻局,從j開始,從右往左找仑扑,不斷遞減變量j的值,我們找到第一個(gè)下標(biāo)3的數(shù)據(jù)比6小蜓竹,于是把數(shù)據(jù)3移到下標(biāo)0的位置储藐,把下標(biāo)0的數(shù)據(jù)6移到下標(biāo)3,完成第一次比較:

下標(biāo) 0 1 2 3 4 5
數(shù)據(jù) 3 2 7 6 8 9

i=0, j=3, k=6

接著蛛碌,開始第二次比較辖源,這次要變成找比k大的了,而且要從前往后找了酝蜒。遞加變量i矾湃,發(fā)現(xiàn)下標(biāo)2的數(shù)據(jù)是第一個(gè)比k大的,于是用下標(biāo)2的數(shù)據(jù)7和j指向的下標(biāo)3的數(shù)據(jù)的6做交換洲尊,數(shù)據(jù)狀態(tài)變成下表:

下標(biāo) 0 1 2 3 4 5
數(shù)據(jù) 3 2 6 7 8 9

i=2, j=3, k=6

稱上面兩次比較為一個(gè)循環(huán)坞嘀。
接著,再遞減變量j丽涩,不斷重復(fù)進(jìn)行上面的循環(huán)比較裁蚁。
本例中進(jìn)行一次循環(huán)后继准,j--移必,得到i==j,一次快排結(jié)束

注意:第一遍快速排序不會(huì)直接得到最終結(jié)果崔泵,只會(huì)把比k大和比k小的數(shù)分到k的兩邊。為了得到最后結(jié)果入篮,需要再次對(duì)k值兩邊的數(shù)組分別執(zhí)行此步驟幌甘,然后再分解數(shù)組,直到數(shù)組不能再分解為止(只有一個(gè)數(shù)據(jù))锅风,才能得到正確結(jié)果遏弱。

  • C語(yǔ)言實(shí)現(xiàn)
void quickSort(int *array, int leftIndex, int rightIndex) {
    if(leftIndex >= rightIndex) {/*如果左邊索引大于或者等于右邊的索引就代表已經(jīng)整理完成一個(gè)組了*/
        return ;
    }
    int i = leftIndex;
    int j = rightIndex;
    int key = array[leftIndex];
    
    while(i < j) {/*控制在當(dāng)組內(nèi)尋找一遍*/
        while(i < j && array[j] >= key) {
            /*而尋找結(jié)束的條件就是,1漱逸、找到一個(gè)小于或者大于key的數(shù)(大于或小于取決于你想升
             序還是降序)2、沒有符合條件1的肮砾,并且i與j的大小沒有反轉(zhuǎn)*/
            j--;/*向前尋找*/
        }
        array[i] = array[j];
        /*找到一個(gè)這樣的數(shù)后就把它賦給前面的被拿走的i的值(如果第一次循環(huán)且key是
         array[left]袋坑,那么就是給key)*/
        
        while(i < j && array[i] <= key) {
            /*這是i在當(dāng)組內(nèi)向前尋找,同上婆誓,不過(guò)注意與key的大小關(guān)系停止循環(huán)和上面相反也颤,
             因?yàn)榕判蛩枷胧前褦?shù)往兩邊扔,所以左右兩邊的數(shù)大小與key的關(guān)系相反*/
            i++;
        }
        array[j] = array[i];
    }
    
    array[i] = key;/*當(dāng)在當(dāng)組內(nèi)找完一遍以后就把中間數(shù)key回歸*/
    quickSort(array, leftIndex, i - 1);/*最后用同樣的方式對(duì)分出來(lái)的左邊的小組進(jìn)行同上的做法*/
    quickSort(array, i + 1, rightIndex);/*用同樣的方式對(duì)分出來(lái)的右邊的小組進(jìn)行同上的做法*/
    /*當(dāng)然最后可能會(huì)出現(xiàn)很多分左右文留,直到每一組的i = j 為止*/
}
  • OC實(shí)現(xiàn)
- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex {
    if (leftIndex >= rightIndex) {//如果數(shù)組長(zhǎng)度為0或1時(shí)返回
        return ;
    }
    NSInteger i = leftIndex;
    NSInteger j = rightIndex;
    //記錄比較基準(zhǔn)數(shù)
    NSInteger key = [array[i] integerValue];
    
    while (i < j) {
        /**** 首先從右邊j開始查找比基準(zhǔn)數(shù)小的值 ***/
        while (i < j && [array[j] integerValue] >= key) {//如果比基準(zhǔn)數(shù)大,繼續(xù)查找
            j--;
        }
        //如果比基準(zhǔn)數(shù)小骑篙,則將查找到的小值調(diào)換到i的位置
        array[i] = array[j];
        
        /**** 當(dāng)在右邊查找到一個(gè)比基準(zhǔn)數(shù)小的值時(shí)森书,就從i開始往后找比基準(zhǔn)數(shù)大的值 ***/
        while (i < j && [array[i] integerValue] <= key) {//如果比基準(zhǔn)數(shù)小,繼續(xù)查找
            i++;
        }
        //如果比基準(zhǔn)數(shù)大躲查,則將查找到的大值調(diào)換到j(luò)的位置
        array[j] = array[i];
    }
    
    //將基準(zhǔn)數(shù)放到正確位置
    array[i] = @(key);
    /**** 遞歸排序 ***/
    //排序基準(zhǔn)數(shù)左邊的
    [self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];
    //排序基準(zhǔn)數(shù)右邊的
    [self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];
}
  • 時(shí)間復(fù)雜度

最好和平均的時(shí)間復(fù)雜度為O(nlogn)
最壞的時(shí)間復(fù)雜度為O(n^2)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秋秤,老刑警劉巖恨胚,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異赃泡,居然都是意外死亡升熊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門页屠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蓖柔,“玉大人,你說(shuō)我怎么就攤上這事况鸣。” “怎么了十减?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)速址。 經(jīng)常有香客問我由驹,道長(zhǎng),這世上最難降的妖魔是什么蔓榄? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任甥郑,我火速辦了婚禮,結(jié)果婚禮上澜搅,老公的妹妹穿的比我還像新娘。我一直安慰自己癌瘾,他們只是感情好饵溅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咬荷,像睡著了一般糖赔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上放典,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天奋构,我揣著相機(jī)與錄音,去河邊找鬼弥臼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛掺栅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播氧卧,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼沙绝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了闪檬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤虚循,失蹤者是張志新(化名)和其女友劉穎为黎,沒想到半個(gè)月后行您,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炕檩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年笛质,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捞蚂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敲霍,死狀恐怖丁存,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情解寝,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布夫偶,位于F島的核電站,受9級(jí)特大地震影響晕窑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杨赤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一截汪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阳柔,春花似錦蚓峦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至召夹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間监憎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工偷霉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留隶债,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓瞒滴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親虏两。 傳聞我的和親對(duì)象是個(gè)殘疾皇子世剖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 排序算法說(shuō)明 (1)排序的定義:對(duì)一序列對(duì)象根據(jù)某個(gè)關(guān)鍵字進(jìn)行排序; 輸入:n個(gè)數(shù):a1,a2,a3,…,an 輸...
    code武閱讀 662評(píng)論 0 0
  • 2018年8月22日祖凫,“洋橋村瀘瀟獎(jiǎng)學(xué)助學(xué)基金會(huì)”正式掛牌酬凳,辦公室設(shè)在“洋橋村委會(huì)”二樓。 拳拳之心稠屠,...
    洋橋村劉海玉閱讀 314評(píng)論 0 0
  • juanjie閱讀 101評(píng)論 0 0
  • 一翎苫、什么是UIApplication 每一個(gè)iOS應(yīng)用程序都有一個(gè)UIApplication實(shí)例,而且是一個(gè)單例 ...
    Q2我沒有瘋閱讀 143評(píng)論 0 0