本文是对时间复杂度以及空间复杂度的一个理解
(这只是在下的粗浅理解,不足的地方还请谅解,欢迎留言提出,后期理解深入后会加以改进)
时间复杂度
由于环境的不同,同样的代码执行所需要的时间是不同的,所以是不能拿来比较的
而函数中执行的次数确实一样的
所以时间复杂度就是程序每个循环中的语句总共会执行的次数
时间复杂度的表示方法——大O渐进表示法
O(f(n))
这里的f(n)是什么呢?
void Test(int n)
{
int iCount = 0;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
iCount++;
}
}
for (int k = 0; k < 2 * n; ++k)
{
iCount++;
}
int count = 10;
while (count--)
{
iCount++;
}
}
上面函数的执行次数可以这样表示 f(n) = n^2 + 2*n + 10
一个算法语句总的执行次数是关于问题规模N的某个函数,记为f(N),N 称为问题的规模。语句总的执行次数记为T(N),当N不断变化时,T(N)也 在变化,算法执行次数的增长速率和f(N)的增长速率相同。则有T(N) = O(f(N)),称O(f(n))为时间复杂度的O渐进表示法
但 f(n) 这个函数又是多少呢?这里就需要时间复杂度的算法了
一般算法O(n)计算方法:
用常数1取代运行时间中的所有加法常数
在修改后的运行次数函数中,只保留最高阶项
去除函数中所有不为次数的常数 例:2*n —> n
所以上面函数的时间复杂度就可以得到了 O(n^2) //由于不会打出n方,只能用n^2表示了,望谅解
空间复杂度
空间复杂度就是函数中创建对象的个数
空间复杂度也是用O 的渐进表示法表示
计算方法可以参考时间复杂度的计算方法,这里就不写了
int Sum(int N)
{
int count = 0;
for (int i = 1; i <= N; ++i)
count += i;
return count;
}
空间复杂度位:O(1) —>只创建了一个临时变量
下面实现两个函数
1、实现二分查找算法的递归及非递归。
//非递归
int Binary_search(int arr[], int len, int a)
{
int left = 0;
int right = len - 1;
int maddle = 0;
while (left <= right)
{
maddle = left + (right - left) / 2;
if (a == arr[maddle])
{
return maddle;
}
else if (a > arr[maddle])
{
left = maddle + 1;
}
else if (a < arr[maddle])
{
right = maddle - 1;
}
}
return -1;
}
int main()
{
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", Binary_search(arr, len, 3));
printf("%d\n", Binary_search(arr, len, 10));
return 0;
}
//递归
//我的这个函数传的参数比较多
int Binary_search(int arr[], int len, int a, int left, int right, int maddle)
{
while (a != arr[maddle])
{
if (left > right)
return -1;
if (a > arr[maddle])
{
left = maddle + 1;
maddle = left + (right - left) / 2;
Binary_search(arr, len / 2, a, left, right, maddle);
}
else
{
right = maddle - 1;
maddle = left + (right - left) / 2;
Binary_search(arr, len / 2, a, left, right, maddle);
}
}
return maddle;
}
int main()
{
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int len = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = len - 1;
int maddle = maddle = left + (right - left) / 2;
printf("%d\n", Binary_search(arr, len, 3, left, right, maddle));
printf("%d\n", Binary_search(arr, len, 10, left, right, maddle));
return 0;
}
这里计算一下时间复杂度与空间复杂度
时间复杂度:
非递归 O(logN) 这里要倒过来理解,一个数找了三次才找到,一次会去掉一半的数,所以总的个数就是2^3=8
所以这里的次数就是 logN
递归 O(logN) 函数每次执行的时间复杂度为O(1),执行递归的次数同非递归的二分查找次数,所以时间复杂度也 是O(logN);
空间复杂度:
非递归 O(1) 递归 O(1) 都只创建了一个临时变量
2、实现斐波那契数列的递归及非递归
//非递归
int recursive(int n)
{
int a = 0;
int b = 1;
int i = 0;
for (i = 1; i < n; i++)
{
if (n == 1)
printf("%d", 1);
else
{
if (i % 2 != 0)
{
a = a + b;
b = a + b;
}
}
}
if (n % 2 == 0)
return a;
else
return b;
}
//递归
int recursive(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return (recursive(n - 1) + recursive(n - 2));
}
时间复杂度:
非递归 O(n) 递归 O(2^n)
空间复杂度:
非递归 O(1) 递归 O(1)