// 一个简单的循环void Fun1(int n){ for(int i = 0; i < n; i++) { printf("%d ", i); }}
这段代码, for 循环执行的次数, 是根据传入的参数来具体决定的, 即循环 n 次。就可以说, 这个函数的 时间复杂度是 O(N)。
看起来非常简单?
那么再看一个例子:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Fun2(int n){ int count = 0; for (int i = 0; i < N ; ++ i) { for (int j = 0; j < N ; ++ j) { ++count; } } for (int k = 0; k < 2 * N ; ++ k) { ++count; } int M = 10; while (M--) { ++count; }}
// 计算Func1的时间复杂度? void Func1(int N) { int count = 0; for (int k = 0; k < 2 * N ; ++k) { ++count; } int M = 10; while (M--) { ++count; } printf("%d\n", count); }
// 计算Func2的时间复杂度? void Func2(int N, int M) { int count = 0; for (int k = 0; k < M; ++k) { ++count; } for (int k = 0; k < N ; ++ k) { ++count; } printf("%d\n", count); }
此函数, 通过分析 拥有两个循环体, 一个循环 M 次, 另一个循环 N 次 按照 大O 渐进表示法, 时间复杂度为 O(M + N)
C
1
2
3
4
5
6
7
8
9
10
// 计算Func3的时间复杂度? void Func3(int N) { int count = 0; for (int k = 0; k < 100; ++k) { ++count; } printf("%d\n", count); }
// 计算BubbleSort的时间复杂度? void BubbleSort(int* a, int n) { assert(a); for (size_t end = n; end > 0; --end) { int exchange = 0; for (size_t i = 1; i < end; ++i) { if (a[i-1] > a[i]) { Swap(&a[i-1], &a[i]); exchange = 1; } } if (exchange == 0) break; } }
// 计算BinarySearch的时间复杂度? int BinarySearch(int* a, int n, int x) { assert(a); int begin = 0; int end = n-1; while (begin < end) { int mid = begin + ((end-begin)>>1); if (a[mid] < x) begin = mid+1; else if (a[mid] > x) end = mid; else return mid; } return -1; }
// 计算BubbleSort的空间复杂度? void BubbleSort(int* a, int n) { assert(a); for (size_t end = n; end > 0; --end) { int exchange = 0; for (size_t i = 1; i < end; ++i) { if (a[i-1] > a[i]) { Swap(&a[i-1], &a[i]); exchange = 1; } } if (exchange == 0) break; } }
分析代码可以看出, 冒泡排序额外使用的空间并没有与 N 发生关联。使用了常量个额外空间 所以 按照 大O 渐进表示法, 空间复杂度为 O(1)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 计算Fibonacci的空间复杂度? // 返回斐波那契数列的前n项 long long* Fibonacci(size_t n) { if(n==0) return NULL; long long * fibArray = (long long *)malloc((n+1) * sizeof(long long)); fibArray[0] = 0; fibArray[1] = 1; for (int i = 2; i <= n ; ++i) { fibArray[i] = fibArray[i - 1] + fibArray [i - 2]; } return fibArray; }
这是使用 数组实现的计算斐波那契数列的 前N 项
分析代码可以看出, 这段代码 使用 malloc 函数开辟了 n+1 个 long long类型的空间, 即额外使用的空间与 N 1:1相关
所以 按照 大O 渐进表示法, 空间复杂度为 O(N)
C
1
2
3
4
5
6
7
8
// 计算阶乘递归Fac的空间复杂度? long long Fac(size_t N) { if(N == 0) return 1; return Fac(N-1)*N; }
递归求N的阶乘
分析代码可以看出, 代码执行需要递归 N 次, 且每次递归都需要开辟函数栈帧, 每次函数栈帧开辟都会消耗常量个空间, 所以是 常量 * N