zoukankan      html  css  js  c++  java
  • 算法---冒泡排序,快速排序,二分查找(折半查找),选择排序,插入排序

    好久没有记录东西了,今天整理记录一些常用的算法

    时间复杂度:算法运行的时间
    空间复杂度:算法运行完所需内存的大小
    是不是稳定的算法:根据排序是相同的数据会不会被移动
     
    一.冒泡排序
     
    1.什么是冒泡排序?
    答:冒泡排序算法的运作如下:(从后往前)
     
    1. 1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    2. 2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
    3. 3.针对所有的元素重复以上的步骤,除了最后一个。
    4. 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
     
    2.时间复杂度 和 空间复杂度
    冒泡排序的时间复杂度:O(n2) 
    冒泡排序的空间复杂度:O(1)
     
    3.代码

    NSMutableArray * array = [NSMutableArray arrayWithObjects: @"1",@"8",@"2",@"7",@"2",@"5",@"9",nil];

        //选择

            for (int  i =0; i<[array count]-1; i++) {

                for (int j = i+1; j<[array count]; j++) {

                    if ([array[i] intValue]>[array[j] intValue]) {

                     //交换

                [array exchangeObjectAtIndex:i withObjectAtIndex:j];

                    }

                }

            }

            NSLog(@"%@",array);

     
    4.是否是稳定算法:是
     
           
     
     
     
    二.快速排序———》递归
     
    1.什么是快速排序?
    答:设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序
    一趟快速排序的算法是:
    1. 1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
      2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
      3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
      4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
      5)重复第3、4步,直到i=j;
    2.        6)然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止
    注意:第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。
     
    2.时间复杂度 和 空间复杂度
    快速排序的时间复杂度:O(n2) 
    快速排序的空间复杂度:O(log 2 N)~O(log n)
    3.代码
    - (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的位置
            NSNumber *temp = array[i];
            array[i] = array[j];
            array[j] = temp;
            NSLog(@"%@",array);
            /**** 当在右边查找到一个比基准数小的值时,就从i开始往后找比基准数大的值 ***/
            while (i < j && [array[i] integerValue] <= key) {//如果比基准数小,继续查找
                i++;
            }
            //如果比基准数大,则将查找到的大值调换到j的位置
            NSNumber *bigTemp = array[j];
            array[j] = array[i];
            array[i] = bigTemp;
            NSLog(@"%@",array);
        }
       
        //将基准数放到正确位置
        array[i] = @(key);
       
        /**** 递归排序 ***/
        //排序基准数左边的
        [self quickSortArray:array withLeftIndex:leftIndex andRightIndex:i - 1];
        //排序基准数右边的
        [self quickSortArray:array withLeftIndex:i + 1 andRightIndex:rightIndex];
    }
     
    4.是否是稳定算法:否
     
     
     
    三. 二分查找(折半查找)
     
    折半查找方法适用于不经常变动而查找频繁的有序列表
     
     
    1.什么是 二分查找?
    答:给一个数,要求查找出来,前提这个数组是一个升序的数组,取数组的中间值,与此数比较,若相等,则返回这个数,若找的数比中间数小,则在中间数的左侧中再找,放在再右侧找,知道找到为止。
    一趟快速排序的算法是:
    1. 1)数组为有序
      2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
      3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
      4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
      5)重复第3、4步,直到i=j;
    2.        6)然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止
    注意:第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。
     
    2.时间复杂度 和 空间复杂度
    二分查找的时间复杂度:O(log n) 
    快速排序的空间复杂度:O(1)
    3.代码
    -(NSInteger)searchNumWithArray:(NSArray *)array Num:(int)num
    {
        if (array.count <= 0) {
            return -1;
        }
        int low = 0;
        int height = (int)array.count - 1;
        while (low <= height) {
            int middle = (height - low)/2 + low;

        if (num == [array[middle] integerValue]) {
            return middle;
        }else if (num < [array[middle] integerValue]){
           
            return middle-1;
        }else{
        
            return middle+1;
        }
        }
       
        return -1;
    }
     
     
     
    四. 选择排序
     
    1.什么是选择排序?
    答:每次找到最小的数才会交换
       2, 1, 5, 4, 9
      第一次排序:1, 2, 5, 4, 9
      第二次排序: 1, 2, 5, 4, 9
      第三次排序: 1, 2, 4, 5, 9
      第四次排序: 1, 2, 4, 5, 9
     
     
    (1)每次排序的时候都需要寻找第n小的数据,并且和array[n-1]发生交换
    (2)等到n个数据都排序好,那么选择排序结束。
     
    2.时间复杂度 和 空间复杂度
    选择排序的时间复杂度:O(n 2) 
    选择排序的空间复杂度:O(1)
    3.代码
    - (NSMutableArray *)SelectSortOC:(NSMutableArray *)arr
    {
        for (int i=0; i < [arr count]-1; i++) {
            for (int j = i+1; j<[arr count]; j++)               {
                if ([arr[i] integerValue] > [arr[j] integerValue]) {
                    [arr exchangeObjectAtIndex:i withObjectAtIndex:j];
                }
            }
           
        }
        return arr;
    }
    4.是否是稳定算法:否
     
     
     
    五. 插入排序
     
    1.什么是插入排序?
    答:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
     
    2.时间复杂度 和 空间复杂度
    插入排序的时间复杂度:O(n 2) 
    插入排序的空间复杂度:O(1)
    3.代码
    - (NSMutableArray *)InsertSortOC:(NSMutableArray *)arr
    {
        for (int i=1; i < [arr count]; i++) {
            for (int j=0; j < i ; j++) {
                if ([arr[i] integerValue] < [arr[j] integerValue]) {
                    [arr exchangeObjectAtIndex:i withObjectAtIndex:j];
                }
            }
        }
        return arr;
    }
     
    4.是否是稳定算法:是
  • 相关阅读:
    mina简介
    idea编辑器jdk版本报错
    设计模式之-工厂模式
    设计模式之-外观模式
    ssm项目中bean注入失败,获取spring中指定bean之解决方案
    Jquery.Page.js 分页插件的使用
    发现某网站低级致命漏洞引发的对多用户系统安全性讨论
    C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一)
    有关C#中使用if else和try catch的问题及效率问题
    C#伪静态实现的方法
  • 原文地址:https://www.cnblogs.com/miaomiaocat/p/6398264.html
Copyright © 2011-2022 走看看