淺談排序的終結者-快速排序算法

真正的才智是剛毅的志向。
大話數據結構修改版.png


序言


快速排序算法是大話數據結構的算法模塊最后的一塊,也是排序算法中最重要的算法,沒有之一.快速排序算法最早是由Tony Hoare 在1962提出.并被列為20世紀十大算法之一.其實,快速排序算法是冒泡排序的升級,都屬于交換排序類.只不過,快速排序的腳步跨的比冒泡排序要大的大,從而在整體上減少了總的比較次數和移動交換次數.那么這么重要的排序算法就有必要研究一下了.


快速排序的基本思想


快速排序的基本思想:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另外一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的.

快速排序算法的基本思想示意圖.jpg


快速排序的算法步驟介紹


看到上面的圖片,我們基本對快速排序算法有了大體的了解,那么接下來,我們看一下快速排序算法是如何實現的.

  • 第一步,在數組A中選取一個關鍵字,稱之為樞軸(pivot),作用就是以這個樞軸為基準,把數組分為兩部分,樞軸左邊的值全部比樞軸的值小,右邊比其小.一般選取數組中的第一個元素當作這個數組的樞軸,(當然,后面的可能樞軸是會發生變化的,例如上圖中,如果再對a部分進行排序,樞軸就會變為a部分中元素的第一個).
  • 第二步,設置兩個變量i、j,排序開始的時候:i=0,j=n-1;(n待排序的部分的元素個數)
  • 第三步,從j開始向前搜索,即由后開始向前搜索(j--),找到第一個小于樞軸的值A[j],將A[j]和A[i]互換;(這里需要注意的是,交換完成之后直接跳到第四步,不會再去尋找第二個比樞軸的值小的元素,同時,要記住j的值是發生變化的).
  • 第四步,從i開始向后搜索,即由前開始向后搜索(i++),找到第一個大于樞軸的A[i],將A[i]和A[j]互換;
  • 第五步,重復第三、四步,直到i=j; (三,四步中,沒找到符合條件的值,即三中A[j]不小于樞軸的值,4中A[i]不大于樞軸的值的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指針位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令循環結束)。

我們看一下,快速排序的過程演示圖.

快速排序演示圖


快速排序的代碼實現


根據上面的快速排序的實現思路,我們可以使用遞歸來進行代碼的設計.下面是OC版的快速排序代碼實現.利用的就是遞歸進行的實現,代碼寫在了ViewController中,因為注釋加的比較詳細,所以就不一一的解釋了.


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController




- (void)viewDidLoad {
    [super viewDidLoad];

  
    NSMutableArray *array = [NSMutableArray arrayWithArray:@[@5,@1,@9,@3,@7,@4,@8,@6,@2]];
    
    [self quickSortWithArray:array left:0 right:array.count-1];
    
    NSLog(@"%@",array);
    
}

#pragma mark ---快速排序算法 ----
-(void)quickSortWithArray:(NSMutableArray *)dataArray left:(NSInteger)left right:(NSInteger)right{
    
    /*如果左邊索引大于或者等于右邊的索引就代表已經整理完成一個組了*/
    if (left >= right) {
        return;
    }
    
    NSInteger i = left;
    NSInteger j = right;
    NSNumber * key = dataArray[left];
    
    /*控制在當組內尋找一遍*/
    while (i< j) {
        
        while (i<j && key <= dataArray[j])
        /*而尋找結束的條件就是,1,找到一個小于或者大于key的數(大于或小于取決于你想升
         序還是降序)2,沒有符合條件1的,并且i與j的大小沒有反轉*/
        {
            
            j--;/*向前尋找*/
            
        }
        dataArray[i] = dataArray[j];
        /*找到一個這樣的數后就把它賦給前面的被拿走的i的值(如果第一次循環且key是
         a[left],那么就是給key)*/
        while(i < j && key >= dataArray[i])
        /*這是i在當組內向前尋找,同上,不過注意與key的大小關系停止循環和上面相反,
         因為排序思想是把數往兩邊扔,所以左右兩邊的數大小與key的關系相反*/
        {
            i++;
        }
        
        dataArray[j] = dataArray[i];
        
    }
    
    dataArray[i] = key;/*當在當組內找完一遍以后就把中間數key回歸*/
    [self quickSortWithArray:dataArray left:left right:i-1];
    /*最后用同樣的方式對分出來的左邊的小組進行同上的做法*/
    [self quickSortWithArray:dataArray left:i+1 right:right];
    /*用同樣的方式對分出來的右邊的小組進行同上的做法*/
    
    /*當然最后可能會出現很多分左右,直到每一組的i = j 為止*/
    
    
    
}


@end



快速排序算法是程序員不得不學的,正如大話中說的那樣,如果有一天BOSS讓你寫一種排列算法,但是你的字典中卻沒有快速排序,那么久趕快度娘一下快速算法存進你的??,別讓同事恥笑..??,好了,快速排序就到這了.下面老習慣,附上OC版的快速排序的Demo.如有任何疑問可在下面的評論區評論,我會及時的回復您的,謝謝.
---> 快速排序OC版Demo??
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    蟻前閱讀 5,214評論 0 52
  • 總結一下常見的排序算法。 排序分內排序和外排序。內排序:指在排序期間數據對象全部存放在內存的排序。外排序:指在排序...
    jiangliang閱讀 1,369評論 0 1
  • 概述:排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序,而外部排序是因排序的數據很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,742評論 0 15
  • 都說習慣決定命運,這句話不假,可怎么去改變一個已經成型的習慣甚至是陋習,真的好困難。或許最好的辦法就是養成新的習慣...
    廖小夭閱讀 317評論 0 1
  • 原問題鏈接:駱和:小資家庭,如何創業? 創業需要很多參考數值:比如資金、人脈、渠道、專業、技術、環境、政策、趨勢....
    駱和先生閱讀 208評論 0 0