看动画轻松理解时间复杂度(一)

算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,比如排序就有前面的十大经典排序和几种奇葩排序,虽然结果相同,但在过程中消耗的资源和时间却会有很大的区别,比如快速排序与猴子排序:)。

那么我们应该如何去衡量不同算法之间的优劣呢?

主要还是从算法所占用的「时间」和「空间」两个维度去考量。

  • 时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。

  • 空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。

本小节将从「时间」的维度进行分析。

什么是大O

当看「时间」二字,我们肯定可以想到将该算法程序运行一篇,通过运行的时间很容易就知道复杂度了。

这种方式可以吗?当然可以,不过它也有很多弊端。

比如程序员小吴的老式电脑处理10w数据使用冒泡排序要几秒,但读者的iMac Pro 可能只需要0.1s,这样的结果误差就很大了。更何况,有的算法运行时间要很久,根本没办法没时间去完整的运行,还是比如猴子排序:)。

那有什么方法可以严谨的进行算法的时间复杂度分析呢?

有的!

「 远古 」的程序员大佬们提出了通用的方法:「 大O符号表示法 」,即 T(n) = O(f(n))

其中 n 表示数据规模 ,O(f(n))表示运行算法所需要执行的指令数,和f(n)成正比。

上面公式中用到的 Landau符号是由德国数论学家保罗·巴赫曼(Paul Bachmann)在其1892年的著作《解析数论》首先引入,由另一位德国数论学家艾德蒙·朗道(Edmund Landau)推广。Landau符号的作用在于用简单的函数来描述复杂函数行为,给出一个上或下(确)界。在计算算法复杂度时一般只用到大O符号,Landau符号体系中的小o符号、Θ符号等等比较不常用。这里的O,最初是用大写希腊字母,但现在都用大写英语字母O;小o符号也是用小写英语字母o,Θ符号则维持大写希腊字母Θ。

注:本文用到的算法中的界限指的是最低的上界。

常见的时间复杂度量级

我们先从常见的时间复杂度量级进行大O的理解:

  • 常数阶O(1)

  • 线性阶O(n)

  • 平方阶O(n²)

  • 对数阶O(logn)

  • 线性对数阶O(nlogn)

O(1)

无论代码执行了多少行,其他区域不会影响到操作,这个代码的时间复杂度都是O(1)

1void swapTwoInts(int &a, int &b){
2  int temp = a;
3  a = b;
4  b = temp;
5}

O(n)

在下面这段代码,for循环里面的代码会执行 n 遍,因此它消耗的时间是随着 n 的变化而变化的,因此可以用O(n)来表示它的时间复杂度。

1int sum int n ){
2   int ret = 0;
3   for ( int i = 0 ; i <= n ; i ++){
4      ret += i;
5   }
6   return ret;
7}

特别一提的是 c * O(n) 中的 c 可能小于 1 ,比如下面这段代码:

1void reverse string &s ) {
2    int n = s.size();
3    for (int i = 0 ; i < n/2 ; i++){
4      swap ( s[i] , s[n-1-i]);
5    }
6}

O(n²)


当存在双重循环的时候,即把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。

 

 1void selectionSort(int arr[],int n){
2   for(int i = 0; i < n ; i++){
3     int minIndex = i;
4     for (int j = i + 1; j < n ; j++ )
5       if (arr[j] < arr[minIndex])
6           minIndex = j;
7
8     swap ( arr[i], arr[minIndex]);
9   }
10}

这里简单的推导一下

  • 当 i = 0 时,第二重循环需要运行 (n - 1) 次
  • 当 i = 1 时,第二重循环需要运行 (n - 2) 次
  • 。。。。。。

不难得到公式:

1(n - 1) + (n - 2) + (n - 3) + ... + 0
2= (0 + n - 1) * n / 2
3= O (n ^2)

当然并不是所有的双重循环都是 O(n²),比如下面这段输出 30n 次 Hello,五分钟学算法:)的代码。

1void printInformation (int n ){
2   for (int i = 1 ; i <= n ; i++)
3        for (int j = 1 ; j <= 30 ; j ++)
4           cout<< "Hello,五分钟学算法:)"<< endl;
5}

O(logn)

 1int binarySearch( int arr[], int n , int target){
2  int l = 0, r = n - 1;
3  while ( l <= r) {
4    int mid = l + (r - l) / 2;
5    if (arr[mid] == target) return mid;
6    if (arr[mid] > target ) r = mid - 1;
7    else l = mid + 1;
8  }
9  return -1;
10}

在二分查找法的代码中,通过while循环,成 2 倍数的缩减搜索范围,也就是说需要经过 log2^n 次即可跳出循环。

同样的还有下面两段代码也是 O(logn) 级别的时间复杂度。

 1  // 整形转成字符串
2  string intToString ( int num ){
3   string s = "";
4   // n 经过几次“除以10”的操作后,等于0
5   while (num ){
6    s += '0' + num%10;
7    num /= 10;
8   }
9   reverse(s)
10   return s;
11  }
1void hello (int n ) {
2   // n 除以几次 2 到 1
3   for ( int sz = 1; sz < n ; sz += sz) 
4     for (int i = 1; i < n; i++)
5        cout<< "Hello,五分钟学算法:)"<< endl;
6}

O(nlogn)

将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logn),也就是了O(nlogn)。

1void hello (){
2  for( m = 1 ; m < n ; m++){
3    i = 1;
4    while( i < n ){
5        i = i * 2;
6    }
7   }
8}

更多复杂度分析内容可以在公众号 五分钟学算法 获取

转载于:https://www.cnblogs.com/fivestudy/p/10113337.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/426225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医疗:ERP进销存系统(8)

进销存系统是为了对企业生产经营中进货、出货、批发销售、付款等进行全程进行&#xff08;从接获订单合同开始&#xff0c;进入物料采购、入库、领用到产品完工入库、交货、回收货款、支付原材料款等&#xff09;跟踪&#xff08;每一步都提供详尽准确的数据&#xff09;、管理…

win10切第二屏幕_Win10特有的31个快捷键,装逼利器,赶快收藏吧!学习电脑知识...

很多快捷键不同版本系统基本相同的&#xff0c;不过&#xff0c;今天推送的这篇更多偏向于win10&#xff0c;因为win10将来必定会形成主流&#xff0c;所以还是值得学习。【WinX】 打开简易版开始菜单。【Wini】 打开设置面板。【WinL】 快速锁屏【WinE】 启动资源管理器&#…

java学习(116):arraylist集合实现类

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; //员工信息类 //date类 public class test50 {private String name;private String sex;private Date birth;public void showme(){System.out.println(this.getName());System.out.p…

BZOJ5020: [THUWC 2017]在美妙的数学王国中畅游(LCT,泰勒展开,二项式定理)

Description 数字和数学规律主宰着这个世界。机器的运转&#xff0c;生命的消长&#xff0c;宇宙的进程&#xff0c;这些神秘而又美妙的过程无不可以用数学的语言展现出来。这印证了一句古老的名言&#xff1a;“学好数理化&#xff0c;走遍天下都不怕。”学渣小R被大学的数学课…

redis存储数据类型_Redis与Memcahe的区别最全整理

经常看到大家只能对比redis和memecache的前两项区别【持久化】和【数据类型】&#xff0c;这里&#xff0c;给整理了最全的memcache和redis的区别&#xff0c;欢迎交流哦缓存(1)【持久化能力】Redis支持持久化&#xff0c;memcache也支持但一般不做持久化(重启丢失数据)(2)【数…

java学习(117):list迭代器和包含方法

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; //员工信息类 //date类 public class test50 {private String name;private String sex;private Date birth;public void showme(){System.out.println(this.getName());System.out.p…

Python转码解压多进程

Python批量转换文件编码格式 Eclipse中看ANSI编码的文件有乱码&#xff0c;所以希望通过python将相关文件转换成utf-8编码。 源&#xff1a;https://www.cnblogs.com/tsbc/p/4450675.html 遍历文件夹 如果文件名是.cpp .h 如果原来的编码不是utf-8,将文件编码格式改成utf-…

某项目的双代号网络图如下所示_2019一级建造师项目管理知识点大全3

更多精彩内容&#xff0c;点击 蓝字 关注我们1Z203000 建设工程项目进度控制1Z203010 建设工程项目进度控制与进度计划系统>>> 1Z203011 项目进度控制的目的考点 1&#xff1a;项目进度控制的工作环节 项目管理各方都有进度控制的任务&#xff0c;但其控制的目标和…

java学习(118):vector类

import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; //员工信息类 //date类 public class test50 {private String name;private String sex;private Date birth;public void showme(){System.out.println(this.getName());System.out.p…

Ipython\Jupyter数据分析工具

使用Python进行数据分析优点   1 Python大量的库为数据分析和处理提供了完整的工具集   2 比起R和Matlab等其他主要用于数据分析的编程语言&#xff0c;Python更全能   3 Python库一直在增加&#xff0c;算法的实现采用更具有创新性的方法   4 Python能和很多语言对接&…

linux搭建vsftp服务器_Linux安装配置vsftp搭建FTP的详细配置

vsftp是very secure ftp的缩写&#xff0c;它最初的发展理念就是构建一个安全的ftp服务。现在它确实是一个非常安全稳定的ftp服务软件&#xff0c;广泛用作在Unix/Linux操作系统中&#xff0c;作为文件服务器使用。安装vsftp这里演示使用yum安装&#xff0c;该软件非常的小&…

java学习(119):set类

public class Goods {//商品实体类private String number;//商品编号private String name;//商品价格private double price;//商品单价private int quantity;//商品数量public void setNumber(String number) {this.number number;}public String getNumber() {return numbe…

分页的limit_20.MySQL中的LIMIT(分页)

对于一次性查询出的大量记录&#xff0c;不仅不便于阅读查看&#xff0c;还会浪费系统效率。MySQL中提供了一个关键字LIMIT&#xff0c;可以限定记录的数量&#xff0c;也可以指定查询从哪一条记录开始(通常用于分页)。1.准备CREATE DATABASE mahaiwuji;USE mahaiwuji;CREATE T…

java学习(120):set的iterator

public class Goods {//商品实体类private String number;//商品编号private String name;//商品价格private double price;//商品单价private int quantity;//商品数量public void setNumber(String number) {this.number number;}public String getNumber() {return numbe…

深入浅出etcd系列 – 心跳和选举

作者&#xff1a;宝爷 校对&#xff1a;DJ 1、绪论 etcd作为华为云PaaS的核心部件&#xff0c;实现了PaaS大多数组件的数据持久化、集群选举、状态同步等功能。如此重要的一个部件&#xff0c;我们只有深入地理解其架构设计和内部工作机制&#xff0c;才能更好地学习华为云Kube…

java学习(121):treeset排序集合

//treeset排序集合 import java.util.*;public class test61{public static void main(String[] args){TreeSet treenew TreeSet();//创建一个采用默认树形自然排序的对象tree.add(new Integer(50));tree.add(new Integer(150));tree.add(new Integer(250));tree.add(new Integ…

修改value_EXCEL批量名称修改

!!嘿嘿,今天给大家更新一章网上算是比较热的一个EXCEL技巧,当然这个是用VBA才能做到的,那就是名称的批量修改.打个比方吧.如果今天你要整理一下,你过往的一些照片,或者文件,这些文件或者照片要按照编辑时间和事件名称来进行编辑,那么你会怎么办?或者说,今天我到西湖去玩了一趟…

java处理url中的特殊字符%等

java处理url中的特殊字符&#xff08;如&,%...&#xff09;URL(Uniform Resoure Locator&#xff0c;统一资源定位器)是Internet中对资源进行统一定位和管理的标志。一个完整的URL包括如下内容&#xff1a;1. 应用协议名称&#xff0c;包括http,ftp,file等标志2. …

java学习(122):treeset自定义排序

//自定义排序 import java.util.*; public class test62 {public static void main(String[] args){TreeSet treenew TreeSet();//创建一个采用默认树形自然排序的对象tree.add(new Integer(50));tree.add(new Integer(150));tree.add(new Integer(250));tree.add(new Integer(…

运行指定代码_JavaScript 运行机制(Event Loop)详解

一、为什么JavaScript是单线程&#xff1f;JavaScript语言的一大特点就是单线程&#xff0c;也就是说&#xff0c;同一个时间只能做一件事。那么&#xff0c;为什么JavaScript不能有多个线程呢&#xff1f;这样能提高效率啊。JavaScript的单线程&#xff0c;与它的用途有关。作…