iOS算法

2018-04-18  本文已影响0人  Junetaurus

排序方法

  1. 选择排序:直接选择排序、堆排序。
  2. 交换排序:冒泡排序、快速排序。
  3. 插入排序:直接插入排序、二分法插入排序、希尔排序。
  4. 归并排序
  5. 基数排序
排序方法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性 复杂性
直接选择排序 O(n2) O(n2) O(n2) O(1) 不稳定 简单
堆排序 O(nlog2n) O(nlog2n) O(nlog2n) O(1) 不稳定 较复杂
冒泡排序 O(n2) O(n2) O(n) O(1) 稳定 简单
快速排序 O(nlog2n) O(n2) O(nlog2n) O(nlog2n) 不稳定 较复杂
直接插入排序 O(n2) O(n2) O(n) O(1) 稳定 简单
希尔排序 O(nlog2n) O(n2) O(n) O(1) 不稳定 较复杂
归并排序 O(nlog2n) O(nlog2n) O(nlog2n) O(n) 稳定 较复杂
基数排序 O(d(n+r)) O(d(n+r)) O(d(n+r)) O(n+r) 稳定 较复杂

选择排序

直接选择排序

- (void)selectionSortWithArray:(NSMutableArray *)array {
    for (NSInteger i = 0; i < array.count; i ++) {
        for (NSInteger j = i + 1; j < array.count; j ++) {
            if (array[i] < array[j]) {
                [array exchangeObjectAtIndex:i withObjectAtIndex:j];
            }
        }
    }
}

堆排序

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

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

交换排序

冒泡排序

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

快速排序

- (void)quickSortWithArray:(NSMutableArray *)array withLeft:(NSInteger)left andRight:(NSInteger)right {
    if (left >= right) return; /*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
    
    NSInteger i = left;
    NSInteger j = right;
    NSInteger key = [array[left] integerValue];
    
    while (i < j) { /*控制在当组内寻找一遍*/
        while (i < j && key <= [array[j] integerValue]) {
            /*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
             序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/
            j--;/*向前寻找*/
        }
        array[i] = array[j]; /*找到一个这样的数后就把它赋给前面的被拿走的i的值*/
        while (i < j && key >= [array[i] integerValue]) {
            /*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
             因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
            i++;/*向后寻找*/
        }
        array[j] = array[i];
    }
    array[i] = [NSNumber numberWithInteger:key];
    
    [self quickSortWithArray:array withLeft:left andRight:i - 1];
    [self quickSortWithArray:array withLeft:i + 1 andRight:right];
}

插入排序

直接插入排序

- (void)insertSort:(NSMutableArray *)array {
    for (NSInteger i = 1; i < array.count; i++) {
        NSInteger j = i;
        NSInteger temp = [array[i] integerValue];
        while (j > 0 && temp < [array[j - 1] integerValue]) {
            [array replaceObjectAtIndex:j withObject:array[j - 1]];
            j--;
        }
        [array replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];
    }
}

折半插入排序(二分插入排序)

- (void)binaryInsertSort:(NSMutableArray *)array {
    for (NSInteger i = 1; i < array.count; i++) {
        NSInteger temp = [array[i] integerValue];
        NSInteger left = 0;
        NSInteger right = i - 1;
        while (left <= right) {
            NSInteger middle = (left + right) / 2;
            if (temp < [array[middle] integerValue]) {
                right = middle - 1;
            }else{
                left = middle + 1;
            }
        }
        for (NSInteger j = i; j > left; j--) {
            [array replaceObjectAtIndex:j withObject:array[j - 1]];
        }
        [array replaceObjectAtIndex:left withObject:[NSNumber numberWithInteger:temp]];
    }
}

希尔排序(缩小增量排序)

+ (void)shellSort:(NSMutableArray *)array {
    NSInteger gap = array.count / 2;
    while (gap >= 1) {
        for (NSInteger i = gap ; i < array.count; i++) {
            NSInteger temp = [array[i] integerValue];
            NSInteger j = i;
            while (j >= gap && temp < [array[j - gap] integerValue]) {
                [array replaceObjectAtIndex:j withObject:array[j - gap]];
                j -= gap;
            }
            [array replaceObjectAtIndex:j withObject:[NSNumber numberWithInteger:temp]];
        }
        gap = gap / 2;
    }
}

归并排序

- (NSMutableArray *)mergeSort:(NSMutableArray *)array withCapacity:(NSInteger)n {
    NSMutableArray *p = [NSMutableArray arrayWithCapacity:n];
    [self mergeSort:array withFirst:0 withLast:n-1 ResultAry:p];
    return p;
}

- (void)mergeSort:(NSMutableArray *)array withFirst:(NSInteger)first withLast:(NSInteger)last ResultAry:(NSMutableArray *)temp{
    if (first < last) {
        NSInteger mid = (first + last) / 2;
        // 左边有序
        [self mergeSort:array withFirst:first withLast:mid ResultAry:temp];
        // 右边有序
        [self mergeSort:array withFirst:mid + 1 withLast:last ResultAry:temp];
        // 将二个有序数列合并
        [self mergearray:array withFirst:first withMid:mid withLast:last ResultAry:temp];
    }
}

- (void)mergearray:(NSMutableArray *)array withFirst:(NSInteger)first withMid:(NSInteger)mid withLast:(NSInteger)last ResultAry:(NSMutableArray *)temp{
    NSInteger i = first, j = mid + 1;
    NSInteger m = mid ,n = last;
    NSInteger k = 0;
    
    while (i <= m && j <= n) {
        if (array[i] <= array[j])  temp[k++] = array[i++];
        else temp[k++] = array[j++];
    }
    
    while (i <= m) temp[k++] = array[i++];
    
    while (j <= n) temp[k++] = array[j++];
    
    for (i = 0; i < k; i++) array[first + i] = temp[i];
}

基数排序

- (void)radixAscendingOrderSort:(NSMutableArray *)array {
    //创建空桶
    NSMutableArray *buckt = [self createBucket];
    //待排数组的最大数值
    NSNumber *maxnumber = [self listMaxItem:array];
    //最大数值的数字位数
    NSInteger maxLength = [self numberLength:maxnumber];
    // 按照从低位到高位的顺序执行排序过程
    for (int digit = 1; digit <= maxLength; digit++) {
        // 入桶
        for (NSNumber *item in array) {
            //确定item 归属哪个桶 以digit位数为基数
            NSInteger baseNumber = [self fetchBaseNumber:item digit:digit];
            NSMutableArray *mutArray = buckt[baseNumber];
            //将数据放入空桶上
            [mutArray addObject:item];
        }
        NSInteger index = 0;
        //出桶
        for (int i = 0; i < buckt.count; i++) {
            NSMutableArray *array = buckt[i];
            //将桶的数据放回待排数组中
            while (array.count != 0) {
                
                NSNumber *number = [array objectAtIndex:0];
                array[index] = number;
                [array removeObjectAtIndex:0];
                index++;
            }
        }
    }
}

//创建空桶
- (NSMutableArray *)createBucket {
    NSMutableArray *bucket = [NSMutableArray array];
    for (int index = 0; index < 10; index++) {
        NSMutableArray *array = [NSMutableArray array];
        [bucket addObject:array];
    }
    return bucket;
}

//数据最大值
- (NSNumber *)listMaxItem:(NSArray *)list {
    NSNumber *maxNumber = list[0];
    for (NSNumber *number in list) {
        if ([maxNumber integerValue] < [number integerValue]) {
            maxNumber = number;
        }
    }
    return maxNumber;
}

//数字的位数
- (NSInteger)numberLength:(NSNumber *)number {
    NSString *string = [NSString stringWithFormat:@"%ld", (long)[number integerValue]];
    return string.length;
}

- (NSInteger)fetchBaseNumber:(NSNumber *)number digit:(NSInteger)digit {
    //digit为基数位数
    if (digit > 0 && digit <= [self numberLength:number]) {
        NSMutableArray *numbersArray = [NSMutableArray array];
        //        number的位数确定
        NSString *string = [NSString stringWithFormat:@"%ld", [number integerValue]];
        for (int index = 0; index < [self numberLength:number]; index++) {
            [numbersArray addObject:[string substringWithRange:NSMakeRange(index, 1)]];
        }
        //        number的位数 是几位数的
        NSString *str = numbersArray[numbersArray.count - digit];
        return [str integerValue];
    }
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读