专栏首页Unity Technology数据结构与算法(三)

数据结构与算法(三)

枕上十年事,江南二老忧,都到心头。

上篇文章中介绍,算法的好坏主要是看完成这个步骤所需要的步数.比如说在

有序数组中插入的效率低,但是查找却很快

常规数组中插入的效率高,反之查找却很慢

当我们在记录这个算法的步骤的时候,不能写出“一个长度为N的有序数组中用二分查找需要的步骤为XX步”.这样写不仅浪费时间又啰嗦,这是我们不想要的,那么有什么办法简洁明了的表示算法的步数的呢?

大O记法

大O记法用来表示操作数据的算法时间复杂度,这里需要多说一句,虽然名字叫"时间复杂度"但是这里所说的并不代表时间,指的仍旧是操作的步数.为什么呢?因为在不同硬件配置的电脑上,运行同一段代码肯定会出现时间差,一个快一点一个慢一点.但是它们运行代码的步骤是不会变的,假如在A电脑上运行的速度为a,在B电脑上运行的速度为b.已知a>b.运行一个长度为N的数组线性查找,我们知道,步数是N,那么,算时间就是a*N必然大于b*N.同一段代码在2台电脑上有不同的运行时间(这里的时间指的是实际时间).但是这个时间差对与算法本身并没有参考价值.所以,虽然叫时间复杂度,但是指的还是步数的多少.

第一篇介绍数据结构的文章中说过:在数组中做读取操作,不管数组有多长,程序只会运行一步,因为数组中的元素都有下标,根据下标能很快的找到对应的元素. 所以,用大O记法表示的话应该是 O(1) 读作"大O1"

那么如果一个操作,同样的不管数组多次,程序都要运行2次才能完成,那么这样的是不是就要记作O(2)了呢?然而并不是.记录算法的时间复杂度依然是O(1).这个1代表的是一个常量,即不管数据的大小,程序运行的步骤总是恒定的.这样的统一记作O(1).

O(1)也称之为常数时间

有一点值得要说明的是:大O记法记录的总是最坏的情况,这样一来最坏情况与最优情况就会表现的不同.所以我们做一个约定,如果没有特殊说明,大O记法表示的总是最坏情况.

如果一个操作是随着数据的增加增加的,比如在长度为N的有序数组中插入大于当前最大值的数,首先程序会比较N次,然后再将数字插入到数组的最后.那么时间复杂度应该为N+1.用大O记法应该是O(N).即代表算法的时间复杂度随着数据的增长而增长,它们之间存在着对应着的关系.所以这样的时间复杂度统一记作O(N).

O(N)也称之为线性时间

那么,上篇文章中提到的第一个算法,二分查找用大O记法该怎么表示呢?它既不是常数时间也不是线性时间,不知道还记不记得,二分查找是长度没增加一倍,它的步数增加1步.这一看就很有规律.

比如

查找2步的有序数组长度是5,

查找3步的有序数组长度是9,

查找4步的有序数组长度是17

...

(注:因为好找中间数,所以数组的长度都加了1)

画出的图应该是下面的样子

显然是对数函数,所以二分查找的时间复杂度的写法应该是O(lon2N),但是一般为了简写都写作O(lonN).

O(logN)称之为对数时间

延申

其实到了上面,完全可以进行下一文章的书写了,但是为了照顾一些学的比较好的,或者想多了解几种算法的时间复杂度与具体的时间复杂度计算方法的人.所以写下下面的延申.

我的写的代码是已 ; 结尾,不排除有其他的代码格式,比如python就没有这样的规定,那么在我们c#编程里,每有一个; 就代表程序执行一次的数据操作.例如:

void Start() {
    Debug.Log("Hello,Unity!\n");      //  需要执行 1 次
}

上面的代码块只需要执行一次. 这个如果用大O记法,记作O(1).

for (int i = 0 ; i<=10,i++)  //执行11次,当i=11的时候跳出循环
{
   Debug .Log ("Hello,Unity!"); //每次循环执行1次
}

上面的代码块就是2*10+1次 如果用大O计法的话应该是外层循环N乘以内层循环O(N*1),所以时间复杂度应该是O(N).

for (int i = 0 ; i<=10,i++)  //执行11次,当i=11的时候跳出循环
{
      for (int j = 0 ; j<=6,j++)  //执行7次,当i=7的时候跳出循环
        {
           Debug .Log ("Hello,Unity!"); //执行60次
          }
}

上面的循环嵌套,当外层循环一次,内循环执行一轮,所以将会是i*j+2,同上计算方法,数据结构算法的时间复杂度表示为O(i*j).如果i=j ,可以写成O(N^2).

void Method(int n) {
    // 第一部分时间复杂度为 O(n^2)
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            printf("Hello, Uniyt!");
        }
    }
    // 第二部分时间复杂度为 O(n)
    for(int j = 0; j < n; j++) {
        printf("Hello, Uniyt!");
    }
}

当遇到上面的情况,并不是将2个循环体的时间复杂度相加,而是取时间复杂度高的那个作为整个算法的时间复杂度.所以上面的时间复杂度应该记为O(N^2).

时间复杂度分析的基本策略是:从内向外分析,从最深层开始分析。如果遇到函数调用,要深入函数进行分析,舍弃算法中时间复杂度比较低的那个模块.

最后,我们来练习一下,答案可以直接写在评论区

第一题:

void Method(int n) {
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            printf("Hello Unity");
        }
    }
}

第二题:

void Method(int n) {
    for (int i = 2; i < n; i++) {
        i *= 2;
        printf(i.Tostring());
    }
}

第三题:

void Method(int n) {
    for (int i = 0; i < n; i++) {
        i *= 3;
        printf(i.Tostring());
    }
}

附加题

void Start()
{
        method(n);
}
void method(int n) {
    if (n <= 1) {
        return 1;
    } else {
        return aFunc(n - 1) + aFunc(n - 2);
    }
}

…END…

本文分享自微信公众号 - 游戏程序员聚集地(Game_Programmer),作者:Jtro

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-01-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数据结构与算法(三)

    当我们在记录这个算法的步骤的时候,不能写出“一个长度为N的有序数组中用二分查找需要的步骤为XX步”.这样写不仅浪费时间又啰嗦,这是我们不想要的,那么有什么办法简...

    LittleU
  • 数据结构与算法(五)

    大O记法是一个判断算法好坏的一个利器,但是在某些时候,虽然大O记法表现的是一样的,但是它们的速度一个要比另一个要快的多.

    LittleU
  • Jtro的源码分享:服务器端使用定时器

    游戏服务器和其他服务器不同,往往需要执行一些“每隔N秒执行一次”的事项,后面的文章会提到的“心跳检测”,便需要定时器。 下面的是一个简单的额定时器的源码,功能...

    LittleU
  • 数据结构与算法(三)

    当我们在记录这个算法的步骤的时候,不能写出“一个长度为N的有序数组中用二分查找需要的步骤为XX步”.这样写不仅浪费时间又啰嗦,这是我们不想要的,那么有什么办法简...

    LittleU
  • 算法——算法的时间与空间复杂度

    PS:如果ax =N(a>0,且a≠1),那么数x叫做以a为底N的对数,记作x=logaN,读作以a为底N的,其中a叫做对数的底数,N叫做真数。

    咸鱼杰克
  • 三种排序方式

    冒泡就像鱼吐得泡泡一样,泡泡越来越大,连起来看就是小泡泡在下面,大泡泡在上面。联想到数字就是大的数字在上面,小的数在下面。给你一个串数字,根据冒泡排序的方法演示...

    微醺
  • BucketSort-桶排序-计数排序

    sr
  • 对数器应用-SelectionSort-选择排序

    sr
  • LeetCode题目30:串联所有单词的子串

    给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

    二环宇少
  • [深度学习工具]·极简安装Dlib人脸识别库

    Dlib是一个现代化的C ++工具箱,其中包含用于在C ++中创建复杂软件以解决实际问题的机器学习算法和工具。它广泛应用于工业界和学术界,包括机器人,嵌入式设备...

    小宋是呢

扫码关注云+社区

领取腾讯云代金券