DSA_02:复杂度分析
2020-03-28 16:01:38来源:博客园 阅读 ()
DSA_02:复杂度分析
真正掌握了复杂度分析,可以说 DSA 便掌握了一小半。
复杂度分析分为:时间复杂度分析、空间复杂度分析。
时间复杂度的定义:
并不是指代码执行的具体、确定时间。
它表示的是一个算法执行效率与数据规模增长的变化趋势。
即便代码需要执行成千上万次,只要它不随数据规模变化而变化,那么它的复杂度就是 O(1)。
空间复杂度的定义:
类似的,它表示空间占用与数据规模增长的变化趋势
同样,哪怕占用再多的空间,只要它不随数据规模变化而变化,那么它的复杂度就是 O(1)。
复杂度的两种表示方法:
1. T(n) 表示法:表示算法随数据规模增长的确切公式,如:T(n) = 4n^2 + 3n + 2。
2. O(n) 表示法:去掉 T(n) 中的常数和低量级,只留下最大的量级,如上式:O(n) = n^2。
3. 同样,若 T(n) = 1000000n^2,O(n) 同样为 n^2。
4. 最常用的 O(n) 表示法。
5. 常数复杂度是 O(1),不存在 O(100),O(1000)等。
6. 我们常说的复杂度 logn,其底数到底是多少呢?
答:一般来说是 2 为底。如果是 5,7,10 等值为底,由高中数学换底公式知道,可以转化为 一个常数*以 2 为低的对数,因此可去掉常数。
以下给出一些常用的复杂度(这几乎包含了所有你会遇到的复杂度):
由低至高:O(1)、O(logn)、O(n)、O(nlogn)、O(n^2)、O(n^3)、O(n^k)、O(2^n)、O(n!)。
两个特殊的复杂度(由两个数据规模决定):O(m+n)、O(mn)。
空间复杂度会比时间复杂度更简单,常用的有:O(1)、O(n)、O(n^2)
一般的复杂度分析笔者就不再啰嗦了,下面重点讲解一下复杂度分析中的:最好、最坏、平均、均摊 时间复杂度
先看一个例子:从一个无序数组中查找某个值是否存在,若存在,则返回下标,否则返回 -1(以 C/C++ 代码给出,不涉及高级语法,相信完全可以看懂)。
// n 是数组大小 int find(int arr[], int n, int target) { int pos = -1; for (int i = 0; i < n; ++i) if (arr[i] == target) pos = i; return pos; }
你可以看出,需要遍历整个数组,其时间复杂度是 O(n),空间复杂度是 O(1)。
当然你肯定也看处问题了,这段代码可以优化,即找到后提前退出:
// n 是数组大小 int find(int arr[], int n, int target) { int pos = -1; for (int i = 0; i < n; ++i) { if (arr[i] == target) { pos = i; break; } } return pos; }
那么问题来了,优化后的时间复杂度还是 O(n) 吗??
现在引出主题:
1. 最好时间复杂度:第一个元素就是我们要查找的,因此时间复杂度是 O(1)
2. 最坏时间复杂度:最后一个元素是我们要查找的,或 target 不在数组内,时间复杂度 O(n)。
3. 平均复杂度:
要查找的变量在数组中的位置,有n+1种情况:在数组的0~n-1位置中和不在数组中。
我们把每种情况下,查找需要遍历的元素个数累加起来,然后再除以n+1, 就可以得到需要遍历的元素个数的平均值,即:
(1+2+3+...+n-1+n+n) / (n+1) = (n(n+3)) / (2(n+1)) 即:O(n)
前面的推导过程中存在的最大问题就是,没有将各种情况发生的概率考虑进去,如果 target 在数组中的概率为 1/2 会怎么样呢?1/3 呢? 1/5 呢?
我们以 1/2 为例计算:
(1 * 1/2n + 2 * 1/2n +...+ n * 1/2n + n * 1/2) = (3n+1) / 4 即:O(n)
尽管上面方法得出的结果均为 O(n),但是我们需要根据实际情况,通常不能丢弃概率。
再看一个例子:有一个数组,当压入数据时数组空间不足了,就将数组扩大至原大小的两倍,将原数据拷贝到新数组中去。
这个操作复杂度是多少呢?
首先要明确:数组空间充足时,压入数组的时间复杂度为 O(1),当空间不足时,需要重新开辟空间,并将原有的 n 个数据拷贝过来,时间复杂度 O(n)。
但是怎么评估整体复杂度呢?
这就用到最后一点:均摊时间复杂度
将一次开辟消费的 O(n) 复杂度,均摊给后面 n-1 次的 O(1) 复杂度,不难得出,均摊复杂度为 O(1)。
这是很重要的复杂度分析方法,后续还会提及。
原文链接:https://www.cnblogs.com/teternity/p/DSA_02.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- tmp 2020-04-01
- DSA_07:递归算法 2020-03-30
- DSA_06:队列 2020-03-29
- DSA_03:数组 2020-03-28
- DSA_04:链表 2020-03-28
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash