iOS 算法大全

作者: 繁华乱世沧桑了谁的容颜 | 来源:发表于2016-12-24 11:56 被阅读321次

    算法其实在实际应用中比较少,因为一般的APP用不到算法也可以很好的开发,但如果真的用到的还是很不好找的,我就在网上收集一些

    1.线性查找

    /// 冒泡排序
    + (void)bubbleSortWithArray:(NSMutableArray *)array withFirst:(NSInteger)first withEnd:(NSInteger)end{
    for (NSInteger i = first ; i < end; i++) {
    for (NSInteger j = end; j > i; j--) {
    if (array[j] < array[j-1]) {
    id temp = array[j];
    array[j] = array[j - 1];
    array[j - 1] = temp;
    }
    }
    }
    }

    + (void)bubbleSortWithArray:(NSMutableArray *)array{
    return [self bubbleSortWithArray:array withFirst:0 withEnd:[array count] - 1];
    }
    

    //求取最小的k个数
    //数组a中从a[p]到a[r]的元素按照x划分,大于或者等于x的在右边,小于x的在左边
    + (NSInteger)partitionModify:(NSMutableArray *)a withP:(NSInteger)p withR:(NSInteger)r withX:(NSInteger)x{
    NSInteger i,j;

    j = r;
    
    for (i = p; i < j; i++) {
        if ([a[i] integerValue] >= x) {
            while (i<j && [a[j] integerValue] >= x) j--;
            if (i != j) {
                id t = a[i];
                a[i] = a[j];
                a[j] = t;
                j--;
            }
            else break;
        }
        }          /*上面的循环结束分为几种情况
     1 i > j 此时必定有 a[i] >= x,否则 a[j+1] = a[i] < x 与 a[j+1] >= x 矛盾 ,如果不是边界,进入if语句
     2 i = j 此时如果 a[i] < x 则a[i+1] = a[j+1] >x 返回 i
     3 当i==p,此时直接返回边界元素下标
     4 当i == r,此时为右边界,此时a[i]肯定为x,返回i - 1,也即r - 1
     */
    
    if ([a[i] integerValue] >= x && i > p) {
        return i - 1;
    }
    return i;
    }
    

    //将r-p+1个数据按五个元素分为一组,分别找出各组的中位数,
    //再将各组的中位数与数组开头的数据在组的顺序依次交换,对这些各组的中位数
    //按同样的方法继续求出中位数,最后得出的整个数组的中位数,利用中位数就可以将数据按照与中位数的比较来划分
    + (NSInteger)selectModify:(NSMutableArray *)array withP:(NSInteger)p withR:(NSInteger)r withK:(NSInteger)k{
    NSInteger i;
    if (r - p + 1 <= 5) {
    [self bubbleSortWithArray:array withFirst:p withEnd:r];
    return [array[p + k - 1] integerValue];
    }

    //将r-p+1个数据按五个元素分为一组,可以分为(r - p + 1) / 5组
    //分别找出各组的中位数,再将各组的中位数与数组开头的数据按组的顺序依次交换
    for (i = 0; i < (r-p+1)/5;i++ ) {
        NSInteger s = p + 5*i,t=s+4;
        [self bubbleSortWithArray:array withFirst:s withEnd:t];
        id temp = array[p + i];
        array[p + i] = array[s + 2];
        array[s + 2] = temp;
    }
    //对这些各组的中位数
    //按同样的方法继续求出中位数,最后得出的整个数组的中位数 x
    NSInteger x = [self selectModify:array withP:p withR: p + (r - p + 1) / 5 - 1 withK:(r - p + 6) / 10];
    
    i = [self partitionModify:array withP:p withR:r withX:x];
    
    NSInteger j = i - p + 1;
    
    if (k <= j) {
        return [self selectModify:array withP:p withR:i withK:k];
    }else{
        return [self selectModify:array withP:i+1 withR:r withK:k-j];
    }
    }
    
    
    + (NSInteger)selectModify:(NSMutableArray *)array withNum:(NSInteger)n{
    if (n == 0 || n > [array count]) return -1;// 未查到
    
    return [self selectModify:array withP:0 withR:[array count] - 1 withK:n];
    }
    

    2.插入排序

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

    3.戴克斯特拉算法

    + (NSArray *)dijkstra_alg:(NSMutableArray *)map  withShotest:(NSMutableArray *)shortest withV:(NSMutableArray *)visited withO:(NSInteger)orig{
    
    NSInteger n = [shortest count];
    if ( n - 1 <= 0) return nil;
    
    // 初始化,第一个顶点求出
    shortest[orig] = @(0);
    visited[orig] = @(YES);
    
     // 要加入n-1个顶点
    for (int p = 0; p != n - 1; p++) {
        // 选出一个距离初始顶点最近的未标记顶点
        int k = -1;
        int min = -1;
        for (int i = 0; i < n; i++) {
            if ([visited[i] compare:@(0)] == NSOrderedSame && [map[orig][i] intValue] != -1) {
                if (min == -1 || min > [map[orig][i] intValue]) {
                   
                    min = [map[orig][i] intValue];
                    k = i;
                }
            }
        }
        // 正确的图生成的矩阵不可能出现K == M的情况
        if (k == -1) {
            NSLog(@"the input map matrix is wrong!");
            return nil;
        }
        
        shortest[k] = @(min);
        visited[k] = @(YES);
        
        for (int i = 0; i < n; i++) {
            
            
            if ([visited[i] compare:@(0)] == NSOrderedSame && [map[k][i] intValue] != -1) {
                int callen = min + [map[k][i] intValue];
                if ([map[orig][i] intValue] == -1 || [map[orig][i] intValue] > callen) {
                    map[orig][i] = @(callen);
                }
            }
        }
    }
    return shortest;
    }
    
    +(NSArray *)dijkstra:(NSMutableArray *)map withOrig:(NSInteger)orig{
    NSInteger n = [map count];
    NSMutableArray *shortest = [NSMutableArray arrayWithCapacity:n];
    NSMutableArray *visited = [NSMutableArray arrayWithCapacity:n];
    for (int i = 0; i < n; i++) {
        [shortest addObject:@(-1)];
        [visited addObject:@(NO)];
    }
    return [self dijkstra_alg:map withShotest:shortest withV:visited withO:orig];
    }
    

    4.动态规划

    + (NSString *)getRandomString:(NSInteger)length{
    NSString *str = @"abcdefghijklmnopqrstuvwxyz";
    NSMutableString *res = [[NSMutableString alloc] initWithCapacity:length];
    for (int i = 0; i < length; i++) {
        NSRange range;
        range.length = 1;
        range.location = arc4random()%length;
        NSString *r = [str substringWithRange:range];
        [res appendString:r];
    }
    return res;
    }
    
    + (NSString *)lcs:(NSString *)str1 withOtherString:(NSString *)str2{
    int length1 = (int)[str1 length];
    int length2 = (int)[str2 length];
    NSMutableArray *p1 = [NSMutableArray arrayWithCapacity:length2 + 1];
    // 构造二维数组记录子问题x[i]和y[i]的LCS的长度
    NSMutableArray *opt = [NSMutableArray arrayWithCapacity:length1 + 1];
    for (int i = 0; i < length2 + 1; i++) {
        [p1 addObject:@0];
    }
    
    for (int i = 0; i < length1 + 1; i++) {
        [opt addObject:p1];
    }
    
    
    
    for (int i = length1 - 1; i >= 0; i--) {
        for (int j = length2 - 1; j >= 0; j--) {
            NSRange range1 = {i,1};
            NSRange range2 = {j,1};
            if ([[str1 substringWithRange:range1] isEqualToString:[str2 substringWithRange:range2]]) {
                opt[i][j] = @([opt[i+1][j+1] integerValue] + 1);
            }else{
                int i1 = [opt[i+1][j] intValue] , i2 = [opt[i][j+1] intValue];
                opt[i][j] = @(MAX(i1,i2));
            }
        }
    }
    
    int i = 0,j = 0;
    NSMutableString *result = [[NSMutableString alloc] init];
    
    while (i < length1 && j < length2) {
        NSRange range1 = {i,1};
        NSRange range2 = {j,1};
        if ([[str1 substringWithRange:range1] isEqualToString:[str2 substringWithRange:range2]]) {
            [result appendString:[str1 substringWithRange:range1]];
            i++;
            j++;
        }else if([opt[i + 1][j] intValue] >= [opt[i][j + 1] intValue]){
            i++;
        }else{
            j++;
        }
    }
    return result;
    }
    

    5.堆排序

    /// 最大堆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];
    }
    }

    //堆排序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];//整理树
    }
    }

    6.二叉树

    /**

    • 生成二叉树
    • @param values 数组
    • @return 二叉树
      */
      + (BinaryTreeNode *)createTreeWithValues:(NSArray *)values {
      BinaryTreeNode *root = nil;
      for (NSInteger i=0; i<values.count; i++) {
      NSInteger value = [(NSNumber *)[values objectAtIndex:i] integerValue];
      root = [[self class] addTreeNode:root value:value];
      }
      return root;
      }

    /**

    • 翻转二叉树(非递归)

    • @param rootNode 根节点

    • @return 翻转后的树根节点(其实就是原二叉树的根节点)
      */
      + (BinaryTreeNode *)invertBinaryTreeWithoutRecursion:(BinaryTreeNode *)rootNode {
      if (!rootNode) { return nil; }
      if (!rootNode.leftNode && !rootNode.rightNode) { return rootNode; }
      NSMutableArray *queueArray = [NSMutableArray array]; //数组当成队列
      [queueArray addObject:rootNode]; //压入根节点
      while (queueArray.count > 0) {
      BinaryTreeNode *node = [queueArray firstObject];
      [queueArray removeObjectAtIndex:0]; //弹出最前面的节点,仿照队列先进先出原则
      BinaryTreeNode *pLeft = node.leftNode;
      node.leftNode = node.rightNode;
      node.rightNode = pLeft;

       if (node.leftNode) {
           [queueArray addObject:node.leftNode];
       }
       if (node.rightNode) {
           [queueArray addObject:node.rightNode];
       }
       }
       return rootNode;
       }
      

    /**

    • 翻转二叉树(又叫:二叉树的镜像)
    • @param rootNode 根节点
    • @return 翻转后的树根节点(其实就是原二叉树的根节点)
      */
      + (BinaryTreeNode *)invertBinaryTree:(BinaryTreeNode *)rootNode {
      if (!rootNode) { return nil; }
      if (!rootNode.leftNode && !rootNode.rightNode) { return rootNode; }
      [self invertBinaryTree:rootNode.leftNode];
      [self invertBinaryTree:rootNode.rightNode];
      BinaryTreeNode *tempNode = rootNode.leftNode;
      rootNode.leftNode = rootNode.rightNode;
      rootNode.rightNode = tempNode;
      return rootNode;
      }

    pragma mark - 遍历二叉树

    /// 先序遍历
    + (void)treeFirstInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block{
    if (block) {
    block(rootNode.value);
    }
    if (rootNode.leftNode) {
    [self treeFirstInformationWithNode:rootNode.leftNode resultBlock:block];
    }
    if (rootNode.rightNode) {
    [self treeFirstInformationWithNode:rootNode.rightNode resultBlock:block];
    }
    }

    /// 中序遍历
    + (void)treeMiddleInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block{

    if (rootNode.leftNode) {
        [self treeMiddleInformationWithNode:rootNode.leftNode resultBlock:block];
    }
    if (block) {
        block(rootNode.value);
    }
    if (rootNode.rightNode) {
        [self treeMiddleInformationWithNode:rootNode.rightNode resultBlock:block];
    }
    }
    

    /// 后序遍历
    + (void)treeLastInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block{
    if (rootNode.leftNode) {
    [self treeLastInformationWithNode:rootNode.leftNode resultBlock:block];
    }

    if (rootNode.rightNode) {
        [self treeLastInformationWithNode:rootNode.rightNode resultBlock:block];
    }
    if (block) {
        block(rootNode.value);
    }
    }
    

    /// 二叉树深度
    + (NSInteger)depathOfTree:(BinaryTreeNode *)rootNode{
    if (!rootNode) return 0;
    if (!rootNode.leftNode && !rootNode.rightNode) return 1;
    NSInteger leftDepth = [self depathOfTree:rootNode.leftNode];
    NSInteger rightDepth = [self depathOfTree:rootNode.rightNode];
    return MAX(leftDepth, rightDepth) + 1;
    }

    /// 二叉树所有节点数 节点数=左子树节点数+右子树节点数+1(根节点)
    + (NSInteger)numberOfNodesInTree:(BinaryTreeNode *)rootNode{
    if (!rootNode) return 0;
    return [self numberOfNodesInTree:rootNode.leftNode] + [self numberOfNodesInTree:rootNode.rightNode] + 1;
    }

    //二叉树中某个节点到根节点的路径
    + (NSArray *)pathOfTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode {
    NSMutableArray *pathArray = [NSMutableArray array];
    [self isFoundTreeNode:treeNode inTree:rootNode routePath:pathArray];
    return pathArray;
    }

    pragma mark - Private SEL

    + (BinaryTreeNode *)addTreeNode:(BinaryTreeNode *)treeNode value:(NSInteger)value {
    //根节点不存在,创建节点
    if (!treeNode) {
        treeNode = [BinaryTreeNode new];
        treeNode.value = value;
        NSLog(@"node:%@", @(value));
    }
    else if (value <= treeNode.value) {
        NSLog(@"to left");
        //值小于根节点,则插入到左子树
        treeNode.leftNode = [[self class] addTreeNode:treeNode.leftNode value:value];
    }
    else {
        NSLog(@"to right");
        //值大于根节点,则插入到右子树
        treeNode.rightNode = [[self class] addTreeNode:treeNode.rightNode value:value];
    }
    return treeNode;
    }
    
    + (BOOL)isFoundTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode routePath:(NSMutableArray *)path {
    
    if (!rootNode || !treeNode) {
        return NO;
    }
    //找到节点
    if (rootNode == treeNode) {
        [path addObject:rootNode];
        return YES;
    }
    //压入根节点,进行递归
    [path addObject:rootNode];
    //先从左子树中查找
    BOOL find = [self isFoundTreeNode:treeNode inTree:rootNode.leftNode routePath:path];
    //未找到,再从右子树查找
    if (!find) {
        find = [self isFoundTreeNode:treeNode inTree:rootNode.rightNode routePath:path];
    }
    //如果2边都没查找到,则弹出此根节点
    if (!find) {
        [path removeLastObject];
    }
    
    return find;
    }
    

    7.二分查找

    + (NSInteger)binarySearchNoRecursion:(NSArray *)srcArray withDes:(NSNumber *)des{
    NSInteger low = 0;
    NSInteger high = [srcArray count] - 1;
    while (low <= high) {
        NSInteger middle = low + ((high + low)>>1);//中间位置计算,low+ 最高位置减去最低位置,右移一位,相当于除2.也可以用(high+low)/2
        if ([des integerValue] == [srcArray[middle] integerValue]) return middle;
        else if([des integerValue] < [srcArray[middle] integerValue]) high = middle - 1;
        else low = middle + 1;
    }
    return -1;
    }
    
    + (NSInteger)binarySearchWithRecursion:(NSArray *)srcArray withDes:(NSNumber *)des{
    NSInteger low = 0;
    NSInteger high = [srcArray count] - 1;
    return [self binSearch:srcArray withLow:low withHigh:high withKey:des];
    }
    
    + (NSInteger)binSearch:(NSArray *)srcArray withLow:(NSInteger)low withHigh:(NSInteger)high withKey:(NSNumber *)key{
    if (low <= high) {
        NSInteger mid = (low + high)/2;
        if ([key integerValue] == [srcArray[mid] integerValue]) return mid;
        else if([key integerValue] < [srcArray[mid] integerValue]) return [self binSearch:srcArray withLow:low withHigh:(mid - 1) withKey:key];
        else return [self binSearch:srcArray withLow:mid+1 withHigh:high withKey:key];
    }else{
        return -1;
    }
    }
    

    8.归并排序

    + (void)mergearray:(NSMutableArray *)ary 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 (ary[i] <= ary[j])  temp[k++] = ary[i++];
        else temp[k++] = ary[j++];
    }
    
    while (i <= m) temp[k++] = ary[i++];
    
    while (j <= n) temp[k++] = ary[j++];
    
    for (i = 0; i < k; i++) ary[first + i] = temp[i];
    }
    
    + (void)mergeSort:(NSMutableArray *)ary withFirst:(NSInteger)first withLast:(NSInteger)last ResultAry:(NSMutableArray *)temp{
    if (first < last) {
        NSInteger mid = (first + last) / 2;
        [self mergeSort:ary withFirst:first withLast:mid ResultAry:temp]; // 左边有序
        [self mergeSort:ary withFirst:mid + 1 withLast:last ResultAry:temp]; // 右边有序
        [self mergearray:ary withFirst:first withMid:mid withLast:last ResultAry:temp];// 将二个有序数列合并
    }
    }
    
    + (NSMutableArray *)mergeSort:(NSMutableArray *)ary withCapacity:(NSInteger)n{
    NSMutableArray *p = [NSMutableArray arrayWithCapacity:n];
    [self mergeSort:ary withFirst:0 withLast:n-1 ResultAry:p];
    return p;
    }
    

    9. 汉诺塔

    + (void)move:(NSInteger)N withA:(NSString *)A withB:(NSString *)B withC:(NSString *)C{
    if ( N == 1 ) {
        NSLog(@"Move disk %ld from %@ to %@\n",N,A,C);
    }else{
        [self move:(N - 1) withA:A withB:C withC:B];
        NSLog(@"Move disk %ld from %@ to %@\n",N,A,C);
        [self move:(N - 1) withA:B withB:A withC:C];
    }
    }
    

    10. 快速排序

    + (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]) {
            j--;
        }
        array[i] = array[j];
        while (i < j && key >= [array[i] integerValue]) {
            i++;
        }
        array[j] = array[i];
    }
    array[i] = [NSNumber numberWithInteger:key];
    
    [[self class] quickSortWithArray:array withLeft:left andRight:i - 1];
    [[self class] quickSortWithArray:array withLeft:i + 1 andRight:right];
    }
    

    11. 冒泡排序

    + (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]) {
                int temp = [array[j] intValue];
                array[j] = array[j + 1];
                array[j + 1] = [NSNumber numberWithInt:temp];
            }
        }
    }
    }
    

    12. 希尔排序

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

    相关文章

      网友评论

        本文标题:iOS 算法大全

        本文链接:https://www.haomeiwen.com/subject/ersrmttx.html