您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

什么是算法的大O表示法

时间:2020-08-01 14:51:57  来源:  作者:

做了这么多年的程序员,是不是一直靠着自己的聪明伶俐在编码,数据结构和算法是前辈们的心血和经验总结,不可错过。

数据结构是利用其存储结构和逻辑结构来有效地组织数据,比如线性的表、栈、队列,非线性的树、图等,而算法是描述运算的过程,良好的算法是建立在有效的数据结构之上的。

评价算法的指标

评价一个算法的好坏,除了他正确性指标外,就是所消耗的时间和空间。

为了方便计算所消耗的时间,需要先作2个假设:

算法与计算机的软硬件无关(硬件好理解,软件比如编程语言、执行器、编译器等);代码中的每个语句所消耗的时间都一样,记作一个时间单位;

举个例子

for (int i = 0; i < n; i++) { //①
  for (int j = 0; j < n; j++) { //②
    c[i][j] = 0; //③
    for (int k = 0; k < n; k++) { //④
      c[i][j] = a[i][k] + b[k][j] + c[i][j]; //⑤
    }
  }
}

计算它所消耗时间的过程如下

  • 语句①需要循环到i=n时才会完结,所以它耗费n+1个时间单位;
  • 语句②同语句①,自己的的循环中耗费n+1个时间单位,但它在①的n次循环体内,所以消耗n*(n+1)个时间单位;
  • 语句③在语句①②循环体内,它们分别循环n次,所以语句③消耗n*n个时间单位;
  • 语句④同③,但它本身执行n+1,所以语句④消耗n*n*(n+1)个时间单位;
  • 语句⑤在语句①②④循环体内,它消耗n*n*n个时间单位;

所以总体消耗的时间为:n+1 + n*(n+1) + n*n+n*n*(n+1)+n*n*n=2n3+3n2+2n+1

算法的时间复杂度

上例最终消耗的时间可以用函数表示:T(n)=2n3+3n2+2n+1,但用这么长的算式评价算法的好坏过于繁冗。实际上它是变量n的函数,表示随着n的增大影响着T(n)的增长率变化,化繁为简可进一步抽象为n的量级函数:T(n)=O(f(n)。T(n)=2n3+3n2+2n+1的最大量级是n3,因此可简化为T(n)=O(n3),这就大O表示法。

计算机科学经常用大O表示算法的复杂度或衡量性能,它主要用于描述在最坏的情况下所花费的时间和空间(内存或磁盘)。

为了更形象,下面列举几个例子,根据计算消耗时间的方法很容易得出结果。

O(1)

O(1)表示算法的执行总是消耗相同的时间,比如

boolean isFirstElementEmpty(List<String> elements){
  return elements.get(0).isEmpty();
}

O(n)

O(n)表示算法的复杂度是线性增长的,与数据集的大小成正比。

boolean ContainsValue(List<String> elements, String value) {
  for (String element : elements) {
    if (element.equals(value)) return true;
  }

  return false;
}

如果不用foreach,使用for会更直观些

boolean ContainsValue(List<String> elements, String value) {
  int n = elements.size();
  for (int i = 0; i < n; i++) {
    if (elements.get(i).equals(value)) return true;
  }

  return false;
}

它是消耗时间单位算式是1+n+1+n+1=2n+3,根据n的量级简化为大O表示即O(n)。

O(n2)

O(n2)表示算法的复杂度与数据集大小的平方成正比,一般的循环嵌套就是这种,随着嵌套的层级增加可能是O(n3)、O(n4)等。

boolean ContainsDuplicates(List<String> elements) {
  for (int i = 0; i < elements.size(); i++) {
    for (int j = 0; j < elements.size(); j++) {
      if (i == j) continue;
      if (elements.get(i).equals(elements.get(j))) return true;
    }
  }

  retrn false;
}

O(2n)

O(2n)表示算法的复杂度与数据集大小成指数增长,比如递归

int Fibonacci(int number) {
  if (number <= 1) return number;

  return Fibonacci(number - 2) + Fibonacci(number - 1);
}

O(log2n)指数复杂度

二分法查找时间复杂度最好的情况是O(1),最坏的情况根据Master定理T(n)=T(n/2)+O(1),所以是O(log2n)。它的原理是对于已经排序的数据集,先取中间值进行对比,成功即返回否则根据对比结果确定下一次的中间值对比,依次类推

int binarySearch(int[] arr, int value) {
  int start = 0, end = arr.length - 1;
  while (start <= end) {
    int middle = (start + end) / 2;
    if (value == arr[middle]) {
      return middle;
    }
    if (value > arr[middle]) {
      start = middle + 1;
    }
    if (value < arr[middle]) {
      end = middle - 1;
    }
  }
  ren -1;
}

算法空间的复杂度

空间的复杂度的计算方法和时间复杂度一样,只是这里假设算法的指令、常数、变量和输入数据用到的寄存器相同,而只计算其用到的辅助空间单元个数。

实际上时间和空间是一对矛盾的冤家,一般情况下要么拿时间换空间,要么拿空间换时间,鱼和熊掌不可兼得。

复杂度对比

算法的复杂度一般从小到大顺序依次是O(1) < O(log2n) < O(n) < O(nlog2n) < O(n2) < O(n3) < O(2n)

什么是算法的大O表示法


Tags:大O表示法   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
做了这么多年的程序员,是不是一直靠着自己的聪明伶俐在编码,数据结构和算法是前辈们的心血和经验总结,不可错过。数据结构是利用其存储结构和逻辑结构来有效地组织数据,比如线性...【详细内容】
2020-08-01  Tags: 大O表示法  点击:(68)  评论:(0)  加入收藏
▌简易百科推荐
前言Kafka 中有很多延时操作,比如对于耗时的网络请求(比如 Produce 是等待 ISR 副本复制成功)会被封装成 DelayOperation 进行延迟处理操作,防止阻塞 Kafka请求处理线程。Kafka...【详细内容】
2021-12-27  Java技术那些事    Tags:时间轮   点击:(1)  评论:(0)  加入收藏
博雯 发自 凹非寺量子位 报道 | 公众号 QbitAI在炼丹过程中,为了减少训练所需资源,MLer有时会将大型复杂的大模型“蒸馏”为较小的模型,同时还要保证与压缩前相当的结果。这就...【详细内容】
2021-12-24  量子位    Tags:蒸馏法   点击:(9)  评论:(0)  加入收藏
分稀疏重建和稠密重建两类:稀疏重建:使用RGB相机SLAMOrb-slam,Orb-slam2,orb-slam3:工程地址在: http://webdiis.unizar.es/~raulmur/orbslam/ DSO(Direct Sparse Odometry)因为...【详细内容】
2021-12-23  老师明明可以靠颜值    Tags:算法   点击:(7)  评论:(0)  加入收藏
1. 基本概念希尔排序又叫递减增量排序算法,它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的;希尔排序是一种不稳定的排序算法...【详细内容】
2021-12-22  青石野草    Tags:希尔排序   点击:(6)  评论:(0)  加入收藏
ROP是一种技巧,我们对execve函数进行拼凑来进行system /bin/sh。栈迁移的特征是溢出0x10个字符,在本次getshell中,还碰到了如何利用printf函数来进行canary的泄露。ROP+栈迁移...【详细内容】
2021-12-15  星云博创    Tags:栈迁移   点击:(19)  评论:(0)  加入收藏
一、什么是冒泡排序1.1、文字描述冒泡排序是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地...【详细内容】
2021-12-15    晓掌柜丶韶华  Tags:排序算法   点击:(16)  评论:(0)  加入收藏
在了解golang的map之前,我们需要了解哈希这个概念。哈希表,又称散列表(Hash table),是根据键(key)而直接访问在内存储存位置的数据结构。也就是说,它通过计算出一个键值的函数,将...【详细内容】
2021-12-07  一棵梧桐木    Tags:哈希表   点击:(13)  评论:(0)  加入收藏
前面文章在谈论分布式唯一ID生成的时候,有提到雪花算法,这一次,我们详细点讲解,只讲它。SnowFlake算法据国家大气研究中心的查尔斯&middot;奈特称,一般的雪花大约由10^19个水分子...【详细内容】
2021-11-17  小心程序猿QAQ    Tags:雪花算法   点击:(24)  评论:(0)  加入收藏
导读:在大数据时代,对复杂数据结构中的各数据项进行有效的排序和查找的能力非常重要,因为很多现代算法都需要用到它。在为数据恰当选择排序和查找策略时,需要根据数据的规模和类型进行判断。尽管不同策略最终得到的结果完...【详细内容】
2021-11-04  华章科技    Tags:排序算法   点击:(37)  评论:(0)  加入收藏
这是我在网上找的资源的一个总结,会先给出一个我看了觉得还行的关于算法的讲解,再配上实现的代码: Original author: Bill_Hoo Original Address: http://blog.sina.com.cn/s/bl...【详细内容】
2021-11-04  有AI野心的电工和码农    Tags: KMP算法   点击:(36)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条