提到数据结构与算法就不得不提时间复杂度和空间复杂度,本人看大部分文章介绍都比较晦涩难懂,就想着用简单的代码示例快速让你理解数据结构与算法的时间空间复杂度。
首先,时间复杂度表示的是使用某个数据结构或者某种算法程序执行所耗费的时间,其次,空间复杂度是使用某个数据结构或者某种算法程序执行需要占用多少内存空间。通过时间复杂度和空间复杂度其实是衡量数据结构和算法执行效率好坏标准。
时间复杂度
常见的时间复杂度如下:
● O(1) 常数阶复杂度
● O(log n) O(nlogn) 对数阶复杂度
● O(n) 线性阶复杂度
● O(n^2) 平方阶复杂度
● O(n^3) 立方阶复杂度
● O(2^n) 指数阶复杂度
● O(n!) 阶乘复杂度
O(1) 常数阶复杂度
执行代码如果不是循环语句或者递归语句,那么代码时间复杂度一般都是 Ο(1)。 Ο(1) 示例代码如下所示:
String str = "我是 O(1) 复杂度"
System.out.println(str);
O(n) 线性阶复杂度
如下所示的一层循环代码程序时间复杂度是 O(n)
for(int i=1;i<n; i++){
System.out.println("我是第"+n+"次执行!");
}
O(n^2) 平方阶复杂度
如下所示的二层循环代码程序时间复杂度是 O(n^2)
for(int i=1;i<n; i++){
for(int j=1;j<n;j++){
System.out.println("我是 O(n^2) 复杂度");
}
}
O(n^3) 立方阶复杂度
for(int i=1;i<n; i++){
for(int j=1;j<n;j++){
for(int z=1;z<n;z++){
System.out.println("我是 O(n^3) 复杂度");
}
}
}
O(log n) O(n logn) 对数阶复杂度
O(log n)
假设 n = 32 x结果将是 1、2 、4、8、16、32 具体执行多少次就是 2^x= n 即 x=log2n 这段代码的时间复杂度就是 O(log2n)。
for(int x=1;x<=n; x=x*2){
System.out.println("我是 O(log n)复杂度");
}
O(nlogn)
for(int i=1;i<n; i++){
for(int x=1;x<=n; x=x*2){
System.out.println("我是 O(log n)复杂度");
}
}
O(2^n) 指数阶复杂度
for(int i=1;i<=Math.pow(2,n); i++){
System.out.println("我是 O(2^n)复杂度");
}
O(n!) 阶乘复杂度
一个正整数的阶乘(英语:factorial)是所有小于及等于该数的正整数的积,并且有0的阶乘为1。自然数n的阶乘写作n!。
亦即n!=1×2×3×…×n。阶乘亦可以递归方式定义:0!=1,n!=(n-1)!×n。
for(int i=1;i<=factorial(n); i++){
System.out.println("我是 O(n!) 阶乘复杂度");
}
public int factorial(int number) {
if (number <= 1)
return 1;
else
return number * factorial(number - 1);
}
时间复杂度性能趋势图如下:
由上图我们可以看出算法时间复杂度由小到大依次为:Ο(1) < Ο(log2n) < Ο(n)<Ο(nlogn) <Ο(n^2) < Ο(n ^3) < Ο(2 ^n)<Ο(n!)
空间复杂度
空间复杂度比较常用的有:O(1)、O(n)、O(n²)
相对于时间复杂度,空间复杂度更简单,分析空间复杂度有2个原则:
- 程序中数组的长度基本上就是你的空间复杂度。例如:开了一个一维的数组,那么你的空间复杂度就是O(n),如果开了一个二维的数组,数组长度是n^
2,那么空间复杂度基本上就是 n^ 2 - 递归算法的空间复杂度 = 每次递归的空间复杂度 * 递归深度。
斐波那契数列递归形式实现:空间复杂度为 O(n)
关于常见的算法和数据结构时间空间复杂度如下图所示: