iOS排序算法

(插入排序、选择排序、交换排序、归并排序、基数排序)

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
我们这里说说八大排序就是内部排序。


1342514529_5795.jpg

自己用iOS写了几个排序,先来个数组:

    NSMutableArray *array = [NSMutableArray arrayWithObjects:@89,@2,@22,@95,@88,@66,@43,@31,@57, nil];

1、直接插入排序
思路:将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
图示:


1342520948_8667.jpg

代码:

-(void)sortingForInsertWithArray:(NSMutableArray *)array{
   for (int i = 1; i<=array.count-1; i++) {
           int j = i-1;
           id temp = array[i];
           while (j>=0 && temp<array[j]) {
               array[j+1] = array[j];
               j--;
           }
           array[j+1] = temp;
   }
}

2、希尔排序
思路:希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序。
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

图示:


1342577299_5077.jpg

代码:

-(void)sortingForShellWithArray:(NSMutableArray *)array{
    int dk = (int)(array.count-1)/2;
    while (dk>=1) {
        [self shellSortingWithArray:array startIndex:dk];
        dk = dk/2;
    }
}
-(void)shellSortingWithArray:(NSMutableArray *)array startIndex:(int)dk{
    for (int i = dk; i<=array.count-1; i+=dk) {
        if (array[i]<array[i-dk]) {
            int j = i-dk;
            id temp = array[i];
            array[i] = array[i - dk];
            while (j>=0&&temp<array[j]) {
                array[j+dk] = array[j];
                j-=dk;
            }
            array[j+dk] = temp;
        }
    }
}

3、简单选择排序
思路:在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。
图示:


1342586432_7130.jpg

代码:

-(void)sortingForSelectWithArray:(NSMutableArray *)array{
    int i,j,k;
    for (i = 0; i<=array.count-1; i++) {
        k = i;
        for (j = i+1; j<=array.count-1; j++) {
            if (array[k] >array[j] ) {
                k = j;
            }
        }
        if (k!=i) {
            id temp = array[i];
            array[i]= array[k];
            array[k]= temp;
        }
    }
}

4、堆排序
思路:堆排序是一种树形选择排序,是对直接选择排序的有效改进。
堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足

时称之为堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最小项(小顶堆)。若以一维数组存储一个堆,则堆对应一棵完全二叉树,且所有非叶结点的值均不大于(或不小于)其子女的值,根结点(堆顶元素)的值是最小(或最大)的。如:
(a)大顶堆序列:(96, 83,27,38,11,09)
(b) 小顶堆序列:(12,36,24,85,47,30,53,91)

初始时把要排序的n个数的序列看作是一棵顺序存储的二叉树(一维数组存储二叉树),调整它们的存储序,使之成为一个堆,将堆顶元素输出,得到n 个元素中最小(或最大)的元素,这时堆的根节点的数最小(或者最大)。然后对前面(n-1)个元素重新调整使之成为堆,输出堆顶元素,得到n 个元素中次小(或次大)的元素。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。称这个过程为堆排序
代码:

-(void)sortingForHeapWithArray:(NSMutableArray *)array{
    for (int i = (int)(array.count -1)/2; i>=0; --i) {
        [self heapSortingWithArray:array startIndex:i arrayifCount:(int)array.count-1];
    }
    for (int i = (int)array.count-1; i>0; --i) {
        id temp = array[i];
        array[i] = array[0];
        array[0] = temp;
        [self heapSortingWithArray:array startIndex:0 arrayifCount:i];
    }
}
-(void)heapSortingWithArray:(NSMutableArray *)array startIndex:(int)startIndex arrayifCount:(int)count{
    id temp = array[startIndex];
    int child = 2*startIndex +1;
    while (child<count) {
        if (child+1<count &&array[child]<array[child+1]) {
            ++child;
        }
        if (array[startIndex]<array[child]) {
            array[startIndex] = array[child];
            startIndex = child;
            child = 2*startIndex+1;
        }else{
            break;
        }
        array[startIndex] = temp;
    }
}

5、冒泡排序
思路:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
图示:


1342782078_9990.jpg

代码:

-(void)sortingForBubblingWithArray:(NSMutableArray *)array{
    
    for (int i=0; i<=array.count-1; i++) {
        for (int j=0; j<array.count-1-i; j++) {
            if (array[j] < array[j+1] ) {
                id string = array[j];
                array[j]= array[j+1];
                array[j+1] = string;
            }
        }
    }
}

6、快速排序
思路:1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。

图示:
a)一趟排序:


1342782317_4426.jpg

b)排序全程:


1342782329_8314.jpg

代码:

-(void)sortingForFastWithArray:(NSMutableArray *)array strartIndex:(int)strartIndex endIndex:(int)endIndex{
    
    if (strartIndex>endIndex) {
        return;
    }
    int i = strartIndex, j = endIndex;
    id  key = array[strartIndex];
    
    while (i<j) {
        
        while (i<j && key>=array[j]) {
            j--;
        }
        array[i] = array[j];
        
        while (i<j && key<=array[i]) {
            i++;
        }
        array[j] = array[i];
    }
    array[i] = key;
    [self sortingForFastWithArray:array strartIndex:strartIndex endIndex:i-1];
    [self sortingForFastWithArray:array strartIndex:i+1 endIndex:endIndex];
}

7、归并排序
思路:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
图示:


1342842633_6751.jpg

代码:

-(void)sortingForMergeWithArray:(NSMutableArray *)array standbyArray:(NSMutableArray *)newArray startIndex:(int)startIndex endIndex:(int)endIndex{
    
    int middle;
    if (startIndex<endIndex) {
        
        middle = (startIndex +endIndex)/2;
        [self sortingForMergeWithArray:array standbyArray:newArray startIndex:startIndex endIndex:middle];
        [self sortingForMergeWithArray:array standbyArray:newArray startIndex:middle+1 endIndex:endIndex];
        
        int i = startIndex,
            j = middle+1,
            k = startIndex;
        
        while (i!=middle+1 && j!=endIndex +1) {
            if (array[i]>=array[j]) {
                newArray[k++] = array[j++];
            }else{
                newArray[k++] = array[i++];
            }
        }
        while (i!=middle+1) {
            newArray[k++] = array[i++];
        }
        while (j!=endIndex+1) {
            newArray[k++] = array[j++];
        }
        for (i = startIndex; i<=endIndex; i++) {
            array[i] = newArray[i];
        }
    }
}

参考文章:http://blog.csdn.net/hguisu/article/details/7776068

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 最近在学习算法,对此也做一个总结: 排序对于任何一个程序员来说,可能都不会陌生。你学的第一个算法,可能就是排序。大...
    被吹落的风阅读 3,159评论 0 28
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    zwb_jianshu阅读 1,133评论 0 0
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    闲云清烟阅读 757评论 0 6
  • 转载自CSDN规速 八大排序算法 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是...
    _小沫阅读 544评论 0 1
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    printf200阅读 768评论 0 0