幾種常用的排序算法以及OC實現(xiàn)

排序算法可以分為內(nèi)部排序和外部排序愉老,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序舌稀,而外部排序是因排序的數(shù)據(jù)很大啊犬,一次不能容納全部的排序記錄,在排序過程中需要訪問外存扩借。

常見的內(nèi)部排序算法有:冒泡排序椒惨、快速排序、插入排序潮罪、希爾排序康谆、選擇排序、堆排序嫉到、歸并排序沃暗、基數(shù)排序等。

算法一:冒泡排序

冒泡排序.gif
算法步驟:
1.比較相鄰的元素何恶。如果第一個比第二個大孽锥,就交換他們兩個
2.對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對细层。這步做完后惜辑,最后的元素會是最大的數(shù)
3.針對所有的元素重復以上的步驟,除了最后一個
4.持續(xù)每次對越來越少的元素重復上面的步驟疫赎,直到?jīng)]有任何一對數(shù)字需要比較
//冒泡排序
-(void)bubbleSort:(NSMutableArray *)mtArr
{
    if (mtArr.count == 0 || mtArr == nil) {
        return;
    }
    for (int i = 0; i < mtArr.count; i ++) {
        for (int j = 0; j < mtArr.count; j ++) {
            if ([mtArr[i] compare:mtArr[j]] == NSOrderedAscending )
            {
                [mtArr exchangeObjectAtIndex:i withObjectAtIndex:j];
            }
        }
    }
}

算法二:快速排序

快速排序.gif
算法步驟:
1.從數(shù)列中挑出一個元素盛撑,稱為 “基準”(pivot)。
2.重新排序數(shù)列捧搞,所有元素比基準值小的擺放在基準前面抵卫,所有元素比基準值大的擺在基準的后面(相同的數(shù)可以到任一邊)。在這個分區(qū)退出之后胎撇,該基準就處于數(shù)列的中間位置介粘。這個稱為分區(qū)(partition)操作。
3.遞歸地(recursive)把小于基準值元素的子數(shù)列和大于基準值元素的子數(shù)列排序晚树。
4.遞歸的最底部情形姻采,是數(shù)列的大小是零或一,也就是永遠都已經(jīng)被排序好了爵憎。雖然一直遞歸下去慨亲,但是這個算法總會退出,因為在每次的迭代(iteration)中纲堵,它至少會把一個元素擺到它最后的位置去巡雨。
//快速排序
-(void)quickSort:(NSMutableArray *)mtArr withLeftIndex:(int)leftIndex andRightIndex:(int)rightIndex
{
    if (leftIndex >= rightIndex ) {
        return;
    }
    int i = leftIndex;
    int j = rightIndex;
    
    int number = [mtArr[i] intValue];
    while (i < j) {
        while (i < j && ([mtArr[j] intValue] >= number)){
            j --;
        }
        [mtArr replaceObjectAtIndex:i withObject:mtArr[j]];
      
        while (i < j && ([mtArr[i] intValue] <= number)) {
            i ++;
        }
        [mtArr replaceObjectAtIndex:j withObject:mtArr[i]];
    }
      mtArr[i] = @(number);
    [self quickSort:mtArr withLeftIndex:leftIndex andRightIndex:i -1];
    [self quickSort:mtArr withLeftIndex:i + 1 andRightIndex:rightIndex];

}

詳細介紹:

算法三:插入排序

插入排序.gif
算法步驟:
1.將第一待排序序列第一個元素看做一個有序序列,把第二個元素到最后一個元素當成是未排序序列
2.從頭到尾依次掃描未排序序列席函,將掃描到的每個元素插入有序序列的適當位置(如果待插入的元素與有序序列中的某個元素相等铐望,則將待插入元素插入到相等元素的后面)
//插入排序
-(void)insertSort:(NSMutableArray *)mtArr
{
    if (mtArr == nil || mtArr.count == 0) {
        return;
    }
   for (int i = 0; i < mtArr.count; i ++) {
        NSNumber  * number = mtArr[i];
        int j = i -1;
        while (j >= 0 && [mtArr[j] compare:number] == NSOrderedDescending) {
            [mtArr replaceObjectAtIndex:j + 1 withObject:mtArr[j]];
            j --;
        }
        [mtArr replaceObjectAtIndex:j + 1 withObject:number];
    }
 }

算法四:希爾排序

希爾排序.gif
算法步驟:
1.選擇一個增量序列t1,t2茂附,…正蛙,tk,其中ti>tj营曼,tk=1
2.按增量序列個數(shù)k乒验,對序列進行k 趟排序
3.每趟排序,根據(jù)對應的增量ti蒂阱,將待排序列分割成若干長度為m 的子序列锻全,分別對各子表進行直接插入排序狂塘。僅增量因子為1 時,整個序列作為一個表來處理鳄厌,表長度即為整個序列的長度
//希爾排序
-(void)shellSort:(NSMutableArray *)mtArr
{
    NSInteger bs = mtArr.count/2 ;
    while (bs > 0) {
        for (NSInteger i = bs; i < mtArr.count; i ++) {
            NSInteger temp = [mtArr[i] integerValue];
            NSInteger j = i;
            while (j >= bs && temp < [mtArr[j - bs] integerValue]) {
                [mtArr replaceObjectAtIndex:j withObject:mtArr[j - bs]];
                j -= bs;
            }
            [mtArr replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];
        }
        bs = bs/2;
    }
}

算法五:選擇排序

選擇排序.gif
算法步驟:
1.首先在未排序序列中找到最熊窈(大)元素,存放到排序序列的起始位置
2.再從剩余未排序元素中繼續(xù)尋找最辛撕俊(大)元素泪漂,然后放到已排序序列的末尾
3.重復第二步,直到所有元素均排序完畢
//選擇排序
-(void)selectionSort:(NSMutableArray *)mtArr
{
    if (mtArr == nil || mtArr.count == 0) {
        return;
    }
    int  minIndex; //最小值索引
    for (int i = 0; i < mtArr.count; i ++) {
        minIndex = i;
        for (int j = i +1; j < mtArr.count; j ++) {
            if (mtArr[minIndex] > mtArr[j]) {
                minIndex = j;
            }
        }
        [mtArr exchangeObjectAtIndex:i withObjectAtIndex:minIndex];
    }
}

算法六:堆排序

堆排序.gif
堆排序(Heapsort)是指利用堆這種數(shù)據(jù)結構所設計的一種排序算法歪泳。堆積是一個近似完全二叉樹的結構萝勤,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節(jié)點。
堆排序的平均時間復雜度為Ο(nlogn) 呐伞。

算法步驟:
1.創(chuàng)建一個堆H[0..n-1]
2.把堆首(最大值)和堆尾互換
3.把堆的尺寸縮小1敌卓,并調(diào)用shift_down(0),目的是把新的數(shù)組頂端數(shù)據(jù)調(diào)整到相應位置
4.重復步驟2,直到堆的尺寸為1

算法七:歸并排序

歸并排序.gif
歸并排序(Merge sort)是建立在歸并操作上的一種有效的排序算法荸哟。該算法是采用分治法(Divide and Conquer)的一個非常典型的應用假哎。

算法步驟:
1.申請空間,使其大小為兩個已經(jīng)排序序列之和鞍历,該空間用來存放合并后的序列舵抹;
2.設定兩個指針,最初位置分別為兩個已經(jīng)排序序列的起始位置
3.比較兩個指針所指向的元素劣砍,選擇相對小的元素放入到合并空間惧蛹,并移動指針到下一位置
4.重復步驟3直到某一指針達到序列尾
5.將另一序列剩下的所有元素直接復制到合并序列尾

算法八:基數(shù)排序

總結:

各種排序的時間復雜度、空間復雜度刑枝、穩(wěn)定性如下圖:


關于時間復雜度:

1.平方階(O(n2))排序:各類簡單排序:直接插入香嗓、直接選擇和冒泡排序
2.線性對數(shù)階(O(nlog2n))排序:快速排序、堆排序和歸并排序装畅。
O(n1+§))排序:§是介于0和1之間的常數(shù)
3.線性階(O(n))排序:基數(shù)排序靠娱,此外還有桶、箱排序

關于穩(wěn)定性:

1.穩(wěn)定的排序算法:冒泡排序掠兄、插入排序像云、歸并排序和基數(shù)排序
2.不是穩(wěn)定的排序算法:選擇排序、快速排序蚂夕、希爾排序迅诬、堆排序

參考:

http://blog.csdn.net/hguisu/article/details/7776068
http://www.reibang.com/p/481c26283d33

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市婿牍,隨后出現(xiàn)的幾起案子侈贷,更是在濱河造成了極大的恐慌,老刑警劉巖等脂,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俏蛮,死亡現(xiàn)場離奇詭異撑蚌,居然都是意外死亡,警方通過查閱死者的電腦和手機嫁蛇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門锨并,熙熙樓的掌柜王于貴愁眉苦臉地迎上來露该,“玉大人睬棚,你說我怎么就攤上這事〗庥祝” “怎么了抑党?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撵摆。 經(jīng)常有香客問我底靠,道長,這世上最難降的妖魔是什么特铝? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任暑中,我火速辦了婚禮,結果婚禮上鲫剿,老公的妹妹穿的比我還像新娘鳄逾。我一直安慰自己,他們只是感情好灵莲,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布雕凹。 她就那樣靜靜地躺著,像睡著了一般政冻。 火紅的嫁衣襯著肌膚如雪枚抵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天明场,我揣著相機與錄音汽摹,去河邊找鬼。 笑死苦锨,一個胖子當著我的面吹牛逼泣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逆屡,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼圾旨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了魏蔗?” 一聲冷哼從身側響起砍的,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎莺治,沒想到半個月后廓鞠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帚稠,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年床佳,在試婚紗的時候發(fā)現(xiàn)自己被綠了滋早。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡砌们,死狀恐怖杆麸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浪感,我是刑警寧澤昔头,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站影兽,受9級特大地震影響揭斧,放射性物質發(fā)生泄漏。R本人自食惡果不足惜峻堰,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一讹开、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捐名,春花似錦旦万、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至梅忌,卻和暖如春狰腌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牧氮。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工琼腔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人踱葛。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓丹莲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親尸诽。 傳聞我的和親對象是個殘疾皇子甥材,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

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

  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序性含,而外部排序是因排序的數(shù)據(jù)很大替废,一次不能容納全部...
    蟻前閱讀 5,186評論 0 52
  • 概述:排序有內(nèi)部排序和外部排序巢价,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序折欠,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,732評論 0 15
  • 概述排序有內(nèi)部排序和外部排序芝发,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大苛谷,一次不能容納全部的...
    Luc_閱讀 2,275評論 0 35
  • 總結一下常見的排序算法辅鲸。 排序分內(nèi)排序和外排序。內(nèi)排序:指在排序期間數(shù)據(jù)對象全部存放在內(nèi)存的排序腹殿。外排序:指在排序...
    jiangliang閱讀 1,346評論 0 1
  • 因為項目需求独悴,需要做個日歷控件。之前沒做過赫蛇,嘗試自己寫寫試試绵患。說寫就寫,開始動手悟耘。。织狐。暂幼。[TOC]不過寫之前需要先...
    fisland閱讀 311評論 0 0