时间复杂度空间复杂度

我们编过不少代码,起初学习的时候我们习惯性的认为,只要代码能正确的运行就ok啦~很少考虑代码的优化带来的好处。今天说一下影响代码性能的两个重要指标--时间复杂度&空间复杂度。

时间复杂度:就是函数(指数学中的函数),具体执行的操作次数。通常用渐进表达式O()来表示。

空间复杂度:对象的个数。占用的空间。

算法分析一般分为三类:最坏情况、平均情况、最好情况。

算法分析要保持大局观,忽略掉常数,关注增长最快的表达式。

我们通常见到的算法的时间复杂度有:

斐波那契数列 (递归:O(2^N)非递归:O(N)

冒泡:O(N^2)

选择:O(N^2)

插入:O(N^2)

这里,主要举两个例子加以说明:

例子1:斐波那契数列


这就是著名的斐波那契数列啦。

下面讲讲斐波那契数列的两种算法,并剖析时间复杂度。

(1)递归算法

<span style="font-size:18px;">#include<iostream>
using namespace std;
#include<assert.h>unsigned long long Fib(long long n)
{assert(n >= 0);return n < 2 ? 1 : Fib(n-1)+Fib(n-2);
}
int main()
{cout<<Fib(5)<<endl;return 0;
}</span>
斐波那契数列的递归算法:由于每一步计算都调用两次递归,即Fib(n-1)= Fib(n-2)+ Fib(n-3) = Fib(n-3)+Fib(n-4)+Fib(n-4)+Fib(n-5)=...  这样下来,就相当于二叉树,所以其时间复杂度为O(2^N),空间复杂度为O(N)。

(2)非递归算法

#include<iostream>
using namespace std;
unsigned long long Fib(long long n)
{long long s0 = 0;long long s1 = 1;long long s = 0;for(int i = 0; i < n;i++){s1 = s0+s1;s0 = s1-s0;	}return s1;
}int main()
{cout<<Fib(5)<<endl;return 0;
}
非递归算法只是在for循环里边数值的相互转换,其时间复杂度为O(N),空间复杂度为O(N)。

例子2:二分查找算法

二分查找的基本思想是将n个元素分成大致相等的两部分,a[n/2]与data做比较,如果data=a[n/2],则找到data,算法中止;如果data<a[n/2],则只要在数组a的左半部分继续搜索data,如果data>a[n/2],则只要在数组a的右半部搜索data.

(1)非递归算法

int BinaryFind(int arr[],int size,int data)
{int left = 0;int right = size-1;while(left <= right)        //区间[]{int mid = left-(left-right)/2;if(arr[mid] > data){right = mid-1;}else if(arr[mid] < data){left = mid+1;}else{return mid;}}
<span style="white-space:pre">	</span>return -1;
}
int main()
{int arr[] = {1,3,5,7,9};int size = sizeof(arr)/sizeof(arr[0]);cout<<BinaryFind(arr,size,5)<<endl;return 0;
}

说起二分查找的非递归算法,我们还有另外一种实现。(要特别注意)

int BinaryFind(int arr[],int size,int data)
{int left = 0;int right = size;          //区间[)while(left < right){int mid = left-(left-right)/2;if(arr[mid] > data){right = mid;}else if(arr[mid] < data){left = mid+1;}else{return mid;}}
<span style="white-space:pre">	</span>return -1;
}
int main()
{int arr[] = {1,3,5,7,9};int size = sizeof(arr)/sizeof(arr[0]);cout<<BinaryFind(arr,size,5)<<endl;return 0;
}
while循环循环的次数就是时间复杂度,即时间复杂度为O(LgN),空间复杂度为O(N)。

(2)递归算法

int BinaryFind_R(int arr[],int data,int left,int right)
{if(left <= right)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>int mid = left-(left-right)/2;
<span style="white-space:pre">		</span>if(arr[mid] > data)
<span style="white-space:pre">			</span>BinaryFind_R(arr,data,left,mid-1);
<span style="white-space:pre">		</span>else if(arr[mid] < data)
<span style="white-space:pre">			</span>BinaryFind_R(arr,data,mid+1,right);
<span style="white-space:pre">		</span>else
<span style="white-space:pre">			</span>return mid;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else
<span style="white-space:pre">		</span>return -1;
}
int main()
{int arr[] = {1,3,5,7,9};int size = sizeof(arr)/sizeof(arr[0]);int left = 0;int right = size - 1;cout<<BinaryFind_R(arr,6,left,right)<<endl;return 0;
}
递归时间复杂度为O(LgN)。


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

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

相关文章

C语言 函数递归例题解析

1.接受一个整形值&#xff08;无符号&#xff09;&#xff0c;把它转换为 字符并打印它模拟实现strlen()函数。3.求n的阶乘4.斐波那契数列总结 1.接受一个整形值&#xff08;无符号&#xff09;&#xff0c;把它转换为 字符并打印它 void fun(int x) {if (x > 9){fun(x/10)…

剖析printf函数

printf是什么&#xff0c;对于起初学习c语言的同学来说肯定都特别的疑惑。在这里&#xff0c;解答一下&#xff1a;它是一个函数。既然是一个函数的话&#xff0c;想必肯定有返回值和参数吧。那么它的返回值和参数是什么呢&#xff1f; 1、看一下这个例子&#xff0c;可能更好…

大端小端详解

文章目录为什么有大端小端&#xff1f;大端&#xff1a;低位放在高地址&#xff0c;高位放在低地址小端&#xff1a;低位放在低地址&#xff0c;高位放在高地址面试考点&#xff1a;代码代码2一道面试题为什么有大端小端&#xff1f; 大端&#xff1a;低位放在高地址&#xff0…

详解volatile关键字

volatile字面意思&#xff1a;易变的。在计算机里&#xff0c;是防止优化的意思&#xff0c;然而是怎么防止优化的呢&#xff1f;待我一一道来哦。 先看这样一个例子&#xff1a; <span style"font-size:18px;">#include<iostream> using namespace std…

C语言 有符号字符型输出 面试题

1.第一题 int main() {int a 128;printf("%u\n", a);system("pause"); } 输出结果 128 #include <stdio.h> #include <stdlib.h>int main() {char a 128;printf("%u\n", a);system("pause"); } 输出结果 42949671…

有趣的链表相关题型

链表&#xff1a;也是线性表的一种。形象的来说&#xff1a; 就像火车的一个个车厢一样&#xff0c;一个个的链起来的。它有一个特点&#xff1a;它的头没有前驱&#xff0c;尾没有后继。 为什么会引入链表这个概念呢&#xff1f;之前我们知道的顺序表&#xff0c;是用数组的形…

有趣的约瑟夫环问题

大家有没有听过约瑟夫环这个问题呢&#xff1f;我们先来看看它是一个什么样的问题~ 约瑟夫环&#xff08;Josephus&#xff09;问题是由古罗马的史学家约瑟夫&#xff08;Flavius Josephus&#xff09;提出的。该问题的说法不一&#xff0c;传说他参加并记录了公元66—70年犹太…

一系列链表题

1、链表的倒序输出&#xff1a;(输出4&#xff0c;3&#xff0c;2&#xff0c;1)在这里&#xff0c;可以使用递归的方式&#xff1a; <span style"font-size:18px;">void Reverse(pNode pHead) {if(pHead){Reverse(pHead->next);cout<<pHead->data…

c++之指针引用

指针&#xff1a;指向一块内存地址的标识。 引用&#xff1a;给已经定义的变量起的别名。 格式&#xff1a; 类型 &引用变量名 已定义的变量名&#xff08;引用变量名和已定义的变量名可以看成是同一个实体&#xff0c;一个改变&#xff0c;另一个也随之改变&#xff0…

python之条件、循环语句

其实&#xff0c;很多语言的语法都是相通的&#xff0c;包括初学python一样。 今天要说的是条件、循环语句。这部分也是相对比较简单的&#xff0c;就python而言&#xff0c;只是书写方式稍作改动罢了。 1、条件语句 &#xff08;1&#xff09;格式&#xff1a; if 判断条件…

静态多态之泛型编程(模板)

起初&#xff0c;我们写不同类型的加法函数是这样写的吧&#xff1a; //Template.h #pragma onceint Add(const int left,const int right) {return leftright; }char Add(const char left,const char right) {return leftright; }float Add(const float left,const float rig…

【数据结构】布隆过滤器原理详解及其代码实现

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

c++详解【继承】

学过c的人都知道&#xff0c;c的三大特性&#xff1a;封装、继承、多态。 我们今天说的是c的继承&#xff0c;那么为什么要引入继承&#xff0c;它有什么特点呢&#xff1f; 首先&#xff0c;继承的特点是&#xff1a;使代码复用&#xff0c;为后面学习多态做铺垫。 继承分为…

【送给Git初学者】

好多人都听过Git吧&#xff0c;目前最流行的分布式版本管理系统。还有好多类似的cvs、svn&#xff08;速度慢、必须联网&#xff0c;这些是集中式版本控制系统&#xff09;..... 那么&#xff0c;它是用来干什么的呢&#xff1f;举个例子可能更好理解吧&#xff01; 比如你写…

远程仓库

上节我们安装好了git&#xff0c;并配置好git&#xff0c;github之间的ssh。这节我们就开始用git管理我们的仓库吧。&#xff08;这节在windows下安装的git bash上给大家演示吧&#xff09; 首先&#xff0c;创建好一个仓库&#xff0c;主要步骤如下&#xff1a; 创建好仓库后…

linux根目录的意义和内容

1.du命令&#xff1a;du [选项] 文件     (1)功能该命令是显示指定文件以及下的所有文件占用系统数据块的情况&#xff0c;如果没有文件&#xff0c;默认为是当前工作目录     -a    显示所有文件对系统数据块的使用情况     -b    显示数据块大小时以字节…

c++详解【智能指针】

智能指针&#xff1f;是一个指针吗&#xff1f;这里给大家说的是&#xff0c;它不是一个指针&#xff0c;但它模拟了指针所具有的功能。那么&#xff0c;为什么要有智能指针的引入呢&#xff1f;看看下面的例子吧~ void FunTest() {int *p new int[10];FILE *pFile fopen(&qu…

c++【深度剖析shared_ptr】

shared_ptr解决了scoped_ptr管理单个对象的缺陷&#xff0c;且解决了防拷贝的问题。shared_ptr可以管理多个对象&#xff0c;并且实现了资源共享。 但是仍然存在一些问题&#xff0c;比如&#xff0c;我们熟悉的双向链表&#xff1a; struct Node { Node(const int& value…

c++详解【new和delete】

说起new和delete&#xff0c;了解过c的人应该都知道吧&#xff0c;它是用来分配内存和释放内存的两个操作符。与c语言中的malloc和free类似。 c语言中使用malloc/calloc/realloc/free进行动态内存分配&#xff0c;malloc/calloc/realloc用来在堆上分配空间&#xff0c;free将申…

Stack/Queue与Vector/List的联系

Vector:(顺序表【数组存储】) 1.当申请的空间不足的时候&#xff0c;需要再次开辟一块更大的空间&#xff0c;并把值拷过去。 2.对于尾删和尾插是比较方便的&#xff0c;只需要改动最后一个元素即可。不会改动原有的空间。适用于多次重复的对尾部插删。 3.顺序存储&#xff…