【数据结构】 复杂度
一 时间复杂度
定义:在计算机科学中,算法的时间复杂度是一个函数式T(N),它定量描述了该算法的运行时间。
程序执行时间 = 二进制指令运行时间*执行次数
例1:
推导大O阶规则
- 时间复杂度函数式T(N)中,只保留最高阶项,去掉那些低阶项,因为当N不断变大时,低阶项对结果影响越来越小,当N无穷大时,就可以忽略不计了。
- 如果最高阶项存在且不是1,则去除这个项目的常数系数,因为当N不断变大,这个系数2对结果影响越来越小,当N无穷大时,就可以忽略不计了。
- T(N)中如果没有N相关的项目,只有常数项,用常数1取代所有加法常数。
总T(N) = N^2 + 2N + 10; 由于 N^2 对T(N)的影响最大,所以T(N) = N^2;
时间复杂度表示: O(N^2);
例2:
总T(N) = 2N + 10;
时间复杂度表示: O(N);
例3:
总T(N、M) = N + M;
时间复杂度表示: O(N+M);
例4:
总T(N) = 100;
时间复杂度表示: O(1);
例5 查找字符:
(1)若要查找的字符在字符串第一个位置,则:T(N) = 1;
(1)若要查找的字符在字符串最后位置,则:T(N) = N;
(1)若要查找的字符在字符串中间位置,则:T(N) = N/2;
因此strchr的时间复杂度分为:
最好情况:O(1)
最坏情况:O(N)
平均情况:O(N)
总结:
通过上面我们会发现,有些算法的时间复杂度存在最好、平均和最坏情况。最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)大O的渐进表示法在实际中一般情况关注的是算法的上界,也就是最坏运行情况。
例6 冒泡排序:
总T(N) = n^2/2 - n/2;
时间复杂度表示: O(N^2);
例7:
2^x = n;
x = log2 n;
时间复杂度表示: O(log n);
例8:
时间复杂度表示: O(n);
二 空间复杂度
空间复杂度也是一个数学表达式,是对一个算法在运行过程中因为算法的需要额外临时开辟的空间。
空间复杂度不是程序占用了多少bytes的空间,因为常规情况每个对象大小差异不会很大,所以空间复杂度算的是变量的个数。
空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。
注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间日经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定
例1 BubbleSort:
空间复杂度表示: O(1);
例2:
空间复杂度表示: O(n);