iOS算法小结

目录: 手写这些代码,三大排序
1.冒泡排序
2.插入排序(少于20条用插入)
3.选择排序
4.快速排序
5.归并
6.堆排序

1、冒泡排序 .时间复杂度 O(n2)
冒泡排序是一种用时间换空间的排序方法,最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序。在这种情况下,每一次比较都需要进行交换运算。举个例子来说,一个数列 5 4 3 2 1 进行冒泡升序排列,第一次大循环从第一个数(5)开始到倒数第二个数(2)结束,比较过程:先比较5和4,4比5小,交换位置变成4 5 3 2 1;比较5和3,3比5小,交换位置变成4 3 5 2 1……最后比较5和1,1比5小,交换位置变成4 3 2 1 5。这时候共进行了4次比较交换运算,最后1个数变成了数列最大数。
第二次大循环从第一个数(4)开始到倒数第三个数(2)结束。进行3次比较交换运算。
……
所以总的比较次数为 4 + 3 + 2 + 1 = 10次
对于n位的数列则有比较次数为 (n-1) + (n-2) + ... + 1 = n * (n - 1) / 2,这就得到了最大的比较次数
而O(N^2)表示的是复杂度的数量级。举个例子来说,如果n = 10000,那么 n(n-1)/2 = (n^2 - n) / 2 = (100000000 - 10000) / 2,相对10^8来说,10000小的可以忽略不计了,所以总计算次数约为0.5 * N^2。 用O(N^2)就表示了其数量级(忽略前面系数0.5)。

//冒泡排序
-(void)bubbleSort:(NSMutableArray*)array int:(int)n
{
    for (int i = 0; i<n-1; ++i) {
        for (int j=0; j<n-i-1; ++j) {
            if ([array[j] intValue] > [array[j+1] intValue]) {
                NSNumber* temp = array[j];
                [array replaceObjectAtIndex:j withObject:array[j+1]];
                [array replaceObjectAtIndex:j+1 withObject:temp];
            }
        }
    }
    NSLog(@"%@",array);
}

2、插入排序
O(n2)
—插入排序:插入即表示将一个新的数据插入到一个有序数组中,并继续保持有序。例如有一个长度为N的无序数组,进行N-1次的插入即能完成排序;
1)第一次,数组第1个数认为是有序的数组,将数组第二个元素插入仅有1个有序的数组中;
2)第二次,数组前两个元素组成有序的数组,将数组第三个元素插入由两个元素构成的有序数组中......
3)第N-1次,数组前N-1个元素组成有序的数组,将数组的第N个元素插入由N-1个元素构成的有序数组中,则完成了整个插入排序。

-(void)insertSortWithArray:(NSArray *)aData{  
    NSMutableArray *data = [[NSMutableArray alloc]initWithArray:aData];  
    for (int i = 1; i < [data count]; i++) {  
        id tmp = [data objectAtIndex:i];  
        int j = i-1;  
        while (j != -1 && [data objectAtIndex:j] > tmp) {  
            [data replaceObjectAtIndex:j+1 withObject:[data objectAtIndex:j]];  
            j--;  
        }  
        [data replaceObjectAtIndex:j+1 withObject:tmp];  
    }  
    NSLog(@"插入排序后的结果:%@",[data description]);  
}  

3、选择排序(Selection sort)
O(n2)
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
选择排序:比如在一个长度为N的无序数组中,
1)在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,
2)第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......
3)第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,
至此选择排序完成。

int main(int argc, const char * argv[])
{
    int array[] = {12,2, 6, 9, 8, 5, 7, 1, 4};
    //为了增加可移植性(采取sizeof())计算数组元素个数count
    int count = sizeof(array) /sizeof(array[0]);
    //
    for (int i = 0; i < count - 1; i++) {   //比较的趟数
        int minIndex = i;//查找最小值
        for (int j = minIndex +1; j < count; j++ ) {
            if (array[minIndex] > array[j]) {
                minIndex = j;
            }
        }
        //如果没有比较到最后还剩余一个数,那么就执行下面的操作
        if (minIndex != i) {
            //交换数据
            int temp = 0;
            temp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = temp;
        }
    }
    return 0;
}

4、快速排序 .时间复杂度 O(n*log2n)
1 )设置两个变量i,j ,排序开始时i = 0,就j = mutableArray.count - 1;
2 )设置数组的第一个值为比较基准数key,key = mutableArray.count[0];
3 )因为设置key为数组的第一个值,所以先从数组最右边开始往前查找比key小的值。如果没有找到,j--继续往前搜索;如果找到则将mutableArray[i]和mutableArray[j]互换,并且停止往前搜索,进入第4步;
4 )从i位置开始往后搜索比key大的值,如果没有找到,i++继续往后搜索;如果找到则将mutableArray[i]和mutableArray[j]互换,并且停止往后搜索;
5 )重复第3、4步,直到i == j(此时刚好执行完第3步或第4部),停止排序;

快速排序.jpg
//快速排序
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@(6), @(1),@(2),@(5),@(9),@(4),@(3),@(30),@(35),@(36),@(7),nil];
[self quickSortArray:arr withLeftIndex:0 andRightIndex:arr.count - 1];

- (void)quickSortArray:(NSMutableArray *)array withLeftIndex:(NSInteger)leftIndex andRightIndex:(NSInteger)rightIndex
{
    if (leftIndex >= rightIndex) {//如果数组长度为0或1时返回
        return ;
    }
    NSInteger i = leftIndex;
    NSInteger j = rightIndex;
    //记录比较基准数
    NSInteger key = [array[i] integerValue];
    while (i < j) {
        /**** 首先从右边j开始查找比基准数小的值 ***/
        while (i < j && [array[j] integerValue] >= key) {//如果比基准数大,继续查找
            j--;
        }
        //如果比基准数小,则将查找到的小值调换到i的位置
        array[i] = array[j];
        /**** 当在右边查找到一个比基准数小的值时,就从i开始往后找比基准数大的值 ***/
        while (i < j && [array[i] integerValue] <= key) {//如果比基准数小,继续查找
            i++;
        }
        //如果比基准数大,则将查找到的大值调换到j的位置
        array[j] = array[i];
    }
    
    //将基准数放到正确位置
    array[i] = @(key);
    /**** 递归排序 ***/
    //排序基准数左边的
    [self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];
    //排序基准数右边的
    [self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];
}

5、归并
时间复杂度O(nlogn)
归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

- (void)mergeSortArray:(NSMutableArray *)array lowIndex:(NSInteger)lowIndex highIndex:(NSInteger)highIndex
{
    if (lowIndex >= highIndex) {
        return;
    }
    NSInteger midIndex = lowIndex + (highIndex - lowIndex) / 2;
    [self mergeSortArray:array lowIndex:lowIndex highIndex:midIndex];
    [self mergeSortArray:array lowIndex:midIndex + 1 highIndex:highIndex];
    [self mergeArray:array lowIndex:lowIndex midIndex:midIndex highIndex:highIndex];
}

- (void)mergeArray:(NSMutableArray *)array lowIndex:(NSInteger)lowIndex midIndex:(NSInteger)midIndex highIndex:(NSInteger)highIndex
{
    for (NSInteger i = lowIndex; i <= highIndex; i ++) {
        self.tempArr[i] = array[i];
    }
   
    NSInteger k = lowIndex;
    NSInteger l = midIndex + 1;
    for (NSInteger j = lowIndex; j <= highIndex; j ++) {
        if (l > highIndex) {
            array[j] = self.tempArr[k];
            k++;
        }else if (k > midIndex)
        {
            array[j] = self.tempArr[l];
            l++;
        }else if ([self.tempArr[k] integerValue] > [self.tempArr[l] integerValue])
        {
            array[j] = self.tempArr[l];
            l++;
        }else
        {
            array[j] = self.tempArr[k];
            k++;
        }
    }
}

6、堆排序
图解排序算法(三)之堆排序

//堆排序time:O(nlgn)
+ (void)heapSort:(NSMutableArray *)list{
    int i , size;
    size = [list count]/1.0;
    // 从子树开始整理树
    for (i = [list count]/1.0 - 1; i >= 0; i--) {
        [self createBiggestHeap:list withSize:size beIndex:i];
    }
    //拆除树
    while (size > 0) {
        [list exchangeObjectAtIndex:size - 1 withObjectAtIndex:0];//将根(最小)与数组最末交换
        size--;//树大小减小
        [self createBiggestHeap:list withSize:size beIndex:0];//整理树
    }
}

/// 最大堆heap  最大/最小优先级队列
+ (void)createBiggestHeap:(NSMutableArray *)list withSize:(int)size beIndex:(int)element{
    int lchild = element * 2 + 1,rchild = lchild + 1;//左右子树
    while (rchild < size) {//子树均在范围内
        //如果比左右子树都小,完成整理
        if (list[element] <= list[lchild] && list[element] <= list[rchild]) return;
        //如果左边最小
        if(list[lchild] <= list[rchild]){
            [list exchangeObjectAtIndex:element withObjectAtIndex:lchild];//把左面的提到上面
            element = lchild;//循环时整理子树
        }else{
            //否则右面最小
            [list exchangeObjectAtIndex:element withObjectAtIndex:rchild];
            element = rchild;
        }
        lchild = element * 2 + 1;
        rchild = lchild + 1;//重新计算子树位置
    }
    //只有左子树且子树小于自己
    if (lchild < size && list[lchild] < list[element]) {
        [list exchangeObjectAtIndex:lchild withObjectAtIndex:element];
    }
}

参考:
http://blog.csdn.net/hguisu/article/details/7776068
文中评论很长....有的指出作者的错误,所以代码要自己要运行验证。

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

推荐阅读更多精彩内容