简单理解iOS7大排序算法

1.插入排序

/**
 插入排序
 解释:默认数组第一个元素为有序序列,将后面一个元素插入前面的有序序列中,从而得到一个新的序列
 eg.
 【初始数组】 48。   65。  33。 46
    i = 1        (48)      65      33    46
    i = 2        (48       65)     33    46
    i = 3        (33       48      65)   46
    i = 4        (33       46      48    65)
 */
+ (NSMutableArray *)insert_sortWithArray:(NSArray *)sortArray {
    

#if 0 //新建 数组 插入
    NSMutableArray *newArray = [NSMutableArray array];
    
    for (int i = 0; i < sortArray.count; i++) {
        
        if (i == 0) {
            [newArray addObject:sortArray[i]];
        }else {
            int index = -1;
            for (int j = 0; j < newArray.count; j++) {
                if ([sortArray[i] integerValue] < [newArray[j] integerValue]) {
                    index = j;
                    break;
                }
            }
            if (index == -1) {
                [newArray addObject:sortArray[i]];
            }else {
                [newArray insertObject:sortArray[i] atIndex:index];
            }
        }
        
    }
    return newArray;
#endif
#if 1  // 原数组替换
    
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:sortArray];
    
    for (int i = 0; i < newArray.count; i++) {
        
        for (int j = 0; j < i; j++) {
            
            if ([newArray[i] integerValue] < [newArray[j] integerValue]) {
                NSString *indexStr = newArray[i];
                // 直接进行数据删除插入 可能会引起 数据改变
                [newArray removeObjectAtIndex:i];
                [newArray insertObject:indexStr atIndex:j];
            }
            
        }
        
    }
    
    return newArray;
    
#endif
}

2.希尔排序

/**
 希尔排序
 增量排序,增量设置为总数的 2/3 或一半
 从增量位置开始,依次与差一个增量的值进行比较,小的移动到前面,比较完后起始位置+1继续比较。
 比较到最后,增量减半,并以此为起始点,重复上一步骤,知道间隔为1为止结束
 */
+ (NSMutableArray *)shell_sortWithArray:(NSArray *)sortArray {
    
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:sortArray];
    
    int shell = (int)newArray.count / 2;
    while (shell >= 1) {
        // 通过半值以后向前对比
        for(int i = shell; i < [newArray count]; i++){
            NSInteger temp = [[newArray objectAtIndex:i] intValue];
            int j = i;
            while (j >= shell && temp < [[newArray objectAtIndex:(j - shell)] intValue]) {
                [newArray replaceObjectAtIndex:j withObject:[newArray objectAtIndex:j - shell]];
                j -= shell;
            }
            [newArray replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];
        }
        shell = shell / 2;
    }
    
    return newArray;
}

3.简单选择排序

/**
 简单选择排序
 选择最小的 放在第一个位置
 通过选择剩下的最小的放在第二个位置,以此类推
 最后一个就是最大的
 */
+ (NSMutableArray *)simpleSelect_sortWithArray:(NSArray *)sortArray {
    
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:sortArray];
    
    for (int i = 0; i < newArray.count; i++) {
        NSInteger temp = [newArray[i] integerValue];
        int tag = i;
        for (int j = i; j < newArray.count; j++) {
            if ([newArray[j] integerValue] < temp) {
                temp = [newArray[j] integerValue];
                tag = j;
            }
        }
        [newArray replaceObjectAtIndex:tag withObject:newArray[i]];
        [newArray replaceObjectAtIndex:i withObject:[NSString stringWithFormat:@"%ld", temp]];
    }
    
    
    return newArray;
}

4.堆排序

/**
 堆排序
 设当前元素在数组中 R [ i ] 表示,那么
 它的左孩子结点是:R [ 2 * i + 1 ];
 它的右孩子结点是:R [ 2 * i + 2 ];
 它的父节点是:R [ ( i - 1 ) / 2 ];
 从小到大排序需要满足
 R [ i ] <= R [ 2 * i + 1 ] && R [ i ] <= R [ 2 * I + 2 ];
 
 */
+ (NSMutableArray *)heap_sortWithArray:(NSArray *)sortArray {
#if 0 // 别人写的
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:sortArray];
    //最后一个元素的索引
        NSInteger endIndex = newArray.count - 1;
        //构建初始堆
    newArray = [self heapCreate:newArray];
        // 进行n-1次循环,完成排序
        while (endIndex > 0) {
            //        NSLog(@"将list[0]:\%@与list[\(endIndex)]:\%@交换", ascendingArr[0], ascendingArr[endIndex]);
            // 最后一个元素和第一元素进行交换
            NSNumber *temp = newArray[0];
            newArray[0] = newArray[endIndex];
            newArray[endIndex] = temp;
            //堆调整
            newArray = [self heapAdjast:newArray withFatherIndex:0 withEndIndex:endIndex];
            // 下一次循环
            endIndex -= 1;
        }
    
#endif
#if 1 // 自己写的
    // 初始化堆序列
    NSMutableArray *newArray = [self heap_create:[NSMutableArray arrayWithArray:sortArray] endIndex:sortArray.count];
    // 堆排序
    //将堆第一个和最后一个做调整后排序
    NSInteger tag = newArray.count - 1;
    while (tag > 0) {
        
        NSString *lastObj = newArray[tag];
        [newArray replaceObjectAtIndex:tag withObject:newArray[0]];
        [newArray replaceObjectAtIndex:0 withObject:lastObj];
        
        tag  -= 1;

        [self heap_create:newArray endIndex:tag];
        
        
    }
#endif
    return newArray;
}

+ (NSMutableArray *)heap_create:(NSMutableArray *)array endIndex:(NSInteger)endIndex{

    // 首先建立初始的堆排序,即 最大值在最上面
    // 从后往前推
    // 最后一个元素的 父节点为
    NSInteger fatherIndex = array.count / 2 - 1;
    
    while (fatherIndex > -1) {
        
        [self heap_sortLoopFatherIndex:fatherIndex endIndex:endIndex array:array];
        fatherIndex -= 1;
    }

    return array;
    
}

// 循环堆排序,判断父节点是否存在子节点 
+ (NSMutableArray *)heap_sortLoopFatherIndex:(NSInteger)fatherIndex endIndex:(NSInteger)endIndex array:(NSMutableArray *)array {
    //初始默认最大值是父节点
    NSInteger tempIndex = fatherIndex;
    // 判断 父节点是否有两个子节点,并比较大小
    if (fatherIndex * 2 + 1 > endIndex) {
        return array;
    }
    
    if (fatherIndex * 2 + 1 <= array.count - 1 && fatherIndex * 2 + 2 <= array.count - 1) {
        NSInteger child1 = [array[fatherIndex * 2 + 1] integerValue];
        NSInteger child2 = fatherIndex * 2 + 2 > endIndex ? child1 - 1 : [array[fatherIndex * 2 + 2] integerValue];
        //判断两个子节点哪个大则初始是哪个, 优先右边
        NSInteger temp = child2 >= child1 ? child2 : child1;
        tempIndex = child2 >= child1 ? fatherIndex * 2 + 2 : fatherIndex * 2 + 1;
        // 判断 子节点和父节点哪个大
        tempIndex = [array[fatherIndex] integerValue] >= temp ? fatherIndex : tempIndex;
       
    }else {
        //如果只存在一个节点
        NSInteger child1 = [array[fatherIndex * 2 + 1] integerValue];
        // 判断子节点和父节点哪个大
        tempIndex = [array[fatherIndex] integerValue] >= child1 ? fatherIndex : fatherIndex * 2 + 1;
    }
    
    // 判断  最大的是否是 父节点
    if (tempIndex != fatherIndex) {
        // 如果不是父节点
        NSString *str = array[tempIndex];
        [array replaceObjectAtIndex:tempIndex withObject:array[fatherIndex]];
        [array replaceObjectAtIndex:fatherIndex withObject:str];
        // 替换完 再判断被替换的是否还有子节点
        if (tempIndex * 2 + 1 < array.count) {
            array = [self heap_sortLoopFatherIndex:tempIndex endIndex:endIndex array:array];
        }
    }
    
    return array;
}


//循环建立初始堆
+ (NSMutableArray *)heapCreate:(NSMutableArray *)array
{
    NSInteger i = array.count/2;
    while (i >= 0) {
        array = [self heapAdjast:array withFatherIndex:i withEndIndex:array.count];
        i -= 1;
    }
    return array;
}
//排序
+ (NSMutableArray *)heapAdjast:(NSMutableArray *)items withFatherIndex:(NSInteger)fatherIndex withEndIndex:(NSInteger)endIndex
{
    
    //开始元素
    NSNumber *temp = items[fatherIndex];
    //先获得左子索引
    NSInteger childIndex = 2 * fatherIndex+1;
    
    while (childIndex < endIndex) {
        // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
        if (childIndex+1 < endIndex && [items[childIndex] floatValue] < [items[childIndex+1] floatValue]) {
            childIndex++;
        }
        // 如果父结点的值已经大于孩子结点的值,则直接结束
        if ([temp floatValue] >= [items[childIndex] floatValue]) {
            break;
        }
        // 把孩子结点的值赋给父结点
        items[fatherIndex] = items[childIndex];
        fatherIndex = childIndex;
        childIndex = 2 * fatherIndex +1;
    }
    items[fatherIndex] = temp;
    return items;
}

5.冒泡排序

/**
 冒泡排序
 两两对比排序
 数组有n个元素, 原则上对比 n-1次
 */
+ (NSMutableArray *)bubble_sortWithArray:(NSArray *)sortArray {
    
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:sortArray];
    for (int i = 0; i < newArray.count; i++) {
        for (int j = i + 1; j < newArray.count; j++) {
            NSString *indexStr = newArray[i];
            if ([indexStr integerValue] > [newArray[j] integerValue]) {
                [newArray replaceObjectAtIndex:i withObject:newArray[j]];
                [newArray replaceObjectAtIndex:j withObject:indexStr];
            }
        }
    }
    return newArray;
}

6.快速排序

/**
 快速排序
 i = 0 j = array.cont - 1
 key = array [ 0 ]
 key从右到左选第一个最小,替换
 key 从左到右选第一个最小,替换
 先排序基数 key左边的
 再排序基数 key右边的序列
 */
+ (NSMutableArray *)fast_sortWithArray:(NSArray *)sortArray {
    
    NSMutableArray *newArray = [NSMutableArray arrayWithArray:sortArray];
    
    [self quickSortArr:newArray withLeftIndex:0 andRightIndex:newArray.count - 1];
    
    return newArray;
    
}

+ (void)quickSortArr:(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 && key <= [array[j] integerValue]) {
            // 当未查找到则继续查找
            j --;
        }
        // 如果比基数小, 替换
        array[i] = array[j];
        
        // 开始从左往右查找比基数大的数
        while (i < j && key >= [array[i] integerValue]) {
            // 如果比基数小 则继续查找
            i ++;
        }
        //如果比基数大则替换
        array[j] = array[i];
    }
    // 将基数放在正确的位置
    array[i] = @(key);
    
    //前面排序
    [self quickSortArr:array withLeftIndex:leftIndex andRightIndex:i -1];
    //后面排序
    [self quickSortArr:array withLeftIndex:i + 1 andRightIndex:rightIndex];
    
}

7.归并排序

/**
 归并排序
 分成2 个或者 2 个以上的表
 然后排序成有序表
 合并成一个新的有序表,然后整合成一个整体的有序表
 */
+ (NSMutableArray *)meger_sortWithArray:(NSArray *)sortArray {
    
    NSMutableArray *newArray = [NSMutableArray arrayWithCapacity:1];
    
        for (NSString *num in sortArray) {
            NSMutableArray *subArray = [NSMutableArray array];
            [subArray addObject:num];
            [newArray addObject:subArray];
        }
        while (newArray.count != 1) {
            NSInteger i = 0;
            while (i < newArray.count - 1) {
                newArray[i] = [self mergeArrayFirstList:newArray[i] secondList:newArray[i + 1]];
                [newArray removeObjectAtIndex:i + 1];
                
                i++;
            }
        }
    return newArray;
}

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

推荐阅读更多精彩内容