数据结构系列—初识算法(二)

1、函数的渐近增长

输入规模 n 在没有限制的情况下,只要超过一个数值 N (比如N=2 使得n > 2),这个函数就总是大于另一个函数。函数是渐近增长的。比如两个函数f(n)、g(n) 如果存在一个整数N ,对于所有的 n > N, 最终
f(n) > g(n),也就是 f(n) 增长渐近快于 g(n)。

//        函数的渐近增长
//        2n+3 算法A
        int index = 0;
        for (int i = 0; i < n; i++) {
            index++;
        }
        for (int i = 0; i < n; i++) {
            index++;
        }
        System.out.println(index);
        System.out.println(index);
        System.out.println(index);

//        3n+1 算法B
        for (int i = 0; i < n; i++) {
            index++;
        }
        for (int i = 0; i < n; i++) {
            index++;
        }
        for (int i = 0; i < n; i++) {
            index++;
        }
        System.out.println(index);
次数2n+32n3n+13n
n=15243
n=27476
n=396109
n=1023203130
n=100203200301300

当输入规模n=1时,算法A 不如 算法B,当n > 2时算法A 优先于算法B,随着 n 的增加 算法A 比 算法B 要优秀(n越大 时间效率上的差异也就越来越大)。

随着 n 的增大,发现最高次项相乘的常数、加法常数、其它次要项是不影响最终算法变化的,所以可以进行忽略。
比如:2n+3、3n+1 常数3和1可以忽略 比较2n、3n即可。(忽略的只是加法常数)

比如 4n+8、2n^2 +1 常数8、1,相乘项4、2可以省略 比较n、n^2即可(略的是最高次项相乘的常数和加法常数)

比如 2n^2 + 3n + 1、2n^3 + 3n + 1,常数1、2,次要项3n都可以省略,只比较n^2 、n^3主项(最高阶项)的阶数即可。(忽略的是最高次项相乘的常数和其它次要项)

结论:判断一个算法的效率时,函数中的常数、最高次项相乘的常数和其它次要项常常可以忽略,更应该关注主要项(最高阶项)的阶数。某个算法随着 n 的增大,会越来越优于另一个算法,或者越来越差于另一个算法。

2、算法时间复杂度

随着规模 n 的增大,算法执行时间的增长率和f(n)的增长率相同。使用O()来表示 即:T(n) = O(f(n))。
一般情况下,随着 n 的增大,T(n)增长最慢的算法为最优算法。还记不记得前面讲的两个求和算法? 他们的时间复杂度分别是:O(n)、O(1)

T(n): 执行次数
n:    问题规模
f(n): 问题规模 n 的某个函数 这个函数可以理解为语句执行次数

1、推导大O阶方法

a、用常数"1"取代运行时间中的所有加法常数。

b、在修改后的运行次数函数中,只保留最高阶项。

c、如果最高阶项存在且不是1,则去除这个项相乘的常数。

2、时间复杂度术语

1、常数阶: O(1)

比如 : 还是前面等差数列求和例子,f(n)=2n+3、f(n)=3

第一步替换加法常数为1——> f(n)=2n+1 f(n)=1,
第二步保留最高项——>f(n)=2n f(n)=1,
第三步最高项不是1去除相乘常数——>f(n)=n f(n)=1。

最终根据T(n) =O(f(n)),两者时间复杂度就出来了O(n)、O(1)

2、线性阶:O(n)

比如 : 等差数列求和那个例子 f(n)=2n+3——>f(n)=n——>O(n)

3、对数阶: O(logn)

log对数是对求幂的逆运算.
2 ^ x = n, x=log2(N),相当于2的多少次方(立方)等于N,比如log2(8)=x,那么就是2^x =8,x=3

int count = 1;

while(count < n){

	count = count * 2;  多少个 2 相乘后大于 n。
	
}

f(n)=logn——>O(logn)

4、平方阶: O(n^2)
比如嵌套循环:

int index = 0;
for (int i = 0; i < n; i++) {
	for (int j = 0; j < n; j++) { 
		index++; 
	}
 }
内部循环是O(n),对于外部循环来说再循环n次,得出结论O(n^2),若是外部 n 改为m,那么就是O(m*n)

上面已经列举出了常用的时间复杂度术语,耗费时间从小打大: O(1) < O(logn) < O(n) < O(n^2)

3、算法空间复杂度

常听到空间换时间、时间换空间。这里的空间在代码中是指存储空间,代码中完全可以通过硬盘或内存的存储来进行换取时间上的高效率。
即 S(n) = O(f(n)) n = 问题规模 f(n) = 关于 n 所占存储空间的函数。

时间复杂度指的是:运行时间的需求。

空间复杂度指的是:空间需求。

4、总结

  • 这几章主要讲了数据结构和算法的一些基本概念,比如数据结构的定义、数据的逻辑结构和物理结构、算法的定义、算法的特性、时间空间复杂度等等。没有最好的算法,只有最适合的。
  • 相信大家已经基本了解了数据结构和算法的相关概念。接下来,会继续讲解常见的数据结构
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值