前言
由数据结构引出时间复杂度和空间复杂度。
数据结构本质:在内存中管理数据——增删查改
一、时间复杂度
时间复杂度指基本操作的执行次数
1.大O的渐进表示法
![](https://i-blog.csdnimg.cn/blog_migrate/c5d3750fc56955b001a859cb7af18fb1.png)
2.时间复杂度实例
//求其时间复杂度
void Func1(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;
}
}
其基本操作执行次数为F(N)=N^2+N+10
使用大O渐进表示法后,去除低阶项为O(N^2)
// 计算Func4的时间复杂度?
void Func4(int N)
{
int count = 0;
for (int k = 0; k < 100; ++k)
{
++count;
}
printf("%d\n", count);
}
值得注意的是,这个时间复杂度为O(1),只要是常数次就是O(1),对于电脑来说十次和一百万次基本没啥差别,所以只要是常数次就是O(1)。
// 计算Func2的时间复杂度?
void Func2(int N)
{
int count = 0;
for (int k = 0; k < 2 * N; ++k)
{
++count;
}
int M = 10;
while (M--)
{
++count;
}
printf("%d\n", count);
}
其运行次数是2N,使用大O渐进表示法后,去除前面的系数为O(N)
const char* strchr(const char* str, int character)
{
while (*str)
{
if (*str == character)
{
return str;
}
else
str++;
}
}
这个函数的时间复杂度在不同情况下不同
// 计算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-1,之后每次冒泡次数少1,是等差数列,最后O(N^2)
// 计算BinarySearch的时间复杂度?
int BinarySearch(int* a, int n, int x)
{
assert(a);
int begin = 0;
int end = n - 1;
// [begin, end]:begin和end是左闭右闭区间,因此有=号
while (begin <= end)
{
int mid = begin + ((end - begin) >> 1);
if (a[mid] < x)
begin = mid + 1;
else if (a[mid] > x)
end = mid - 1;
else
return mid;
}
return -1;
}
故为O(logN)
看上去很厉害,实际上很少使用,因为前提有序
这个递归像是一个三角形,但是因为到了2就不继续下去了,所以右边阴影部分是缺少的,但是仍近似认为是满的
二、空间复杂度
1.概念及注意
空间复杂度没有时间复杂度重要,因为现在电脑的内存是相当大的,所以在做题时一般对空间复杂度没要求,甚至我们经常会使用拿时间换空间的方法做题
2.空间复杂度实例
// 计算BubbleSort的空间复杂度?
//O(1)
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;
}
}
如冒泡排序,计算空间复杂度时就不计算已经开好的数组的大小,只将函数中临时占用的变量算进去
值得注意的是下面这个
即时间复杂度需要将所有的消耗加起来,空间复杂度只需要算栈帧最大建立了多少层,最多的时候有多少变量,计算它的深度,同一级的用一块栈帧
因为调用后销毁栈帧不是真的销毁了,而是清除了栈帧上的数据
类似于酒店退房,你虽然退房了,但是房子还在,别人还能使用
总结
这就是数据结构初阶关于时间复杂度和空间复杂度的知识。