算法的复杂度分为时间复杂度和空间复杂度。
时间复杂度
时间复杂度的理解:
1. 一个函数,用来计算的是执行基本操作的次数,而非时间。 2.算法分为最好情况、最坏情况和平均情况,时间复杂度的计量关注的是算法的最坏情况。 3.一个算法的最坏情况的运行时间是在任意输入下的运行时间的上界,以最坏代表最全。 4.递归算法的时间复杂度:递归总次数*每次递归次数。
时间复杂度的函数表示:
T(N)=O(f(N)),称O(f(N))为时间复杂度的O渐进表示法。时间复杂度的书写要求:
1. O(1)不是代表常数次,而是代表一次。 2. 在有两个未知数时,并且不知m、n大小时, 则f(n)=O(m+n)——函数分别求值时 f(n)=O(m*n)——函数循环嵌套时 3.常数次可忽略 (2*n)——f(n)=O(n)
代码分析
eg1:
void Test1(int m, int n)// f(n,m) = 2*m*n == O(m*n)
{
int iCount = 0;
for (int i = 0; i < 2*m ; ++i)
{
for (int j = 0; j < n ; ++j)
{
iCount++;
}
}
}
// f(n,m) = 2*m*n == O(m*n)
eg2:
void Test2(int n)
{
int iCount = 0;
for (int iIdx = 0; iIdx < 10; ++iIdx)
{
iCount++;
}
for (int iIdx = 0; iIdx < 2*n; ++iIdx)
{
iCount++;
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
iCount++;
}
}
}
// f(n) =n^2+2*n+10 == O(n)=n^2
eg3:
int factorial(int n)//求n的阶乘,递归法
{
if(n<=1)
return 1;
else
{
return n*factorial(n-1);
}
}
常见的时间复杂度:(七种)
O(1)——常数型
O(n)——线性型
O(n^2)——平方型
O(n^3)——立方型
O(2^n)——指数型
O(log2N)——对数型
O(Nlog2N)——二维型
空间复杂度
空间复杂度的理解:1.算法执行过程中辅助空间的个数,而非所占空间的大小 2.递归算法的空间复杂度:递归总深度*每次递归所需的辅助空间个数。
空间复杂度的书写要求:
1.常数个辅助空间时,都用O(1)表示
2.递归算法中,若是单线程的递归——求递归深度最深的那一次所需要的辅助空间的个数
(单线程——过程不可同时进行;双线程:过程可同时进行。)
代码分析:
eg1:
int Sum(int N)
{
int count = 0;
for(int i = 1; i <= N; ++i)
{
count += i;
}
return count;
}
空间复杂度:O(n)=1
实例分析:
1.斐波那契数列
——迭代法
int main()
{
int n = 5;
int fib(int n);
printf("%d", fib(n));//1 1 2 3 5 8 13 21 34
system("pause");
return 0;
}
int fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
if(n<2)
return n;
while (n > 2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
//时间复杂度:O(n)——循环次数为n-1次
//空间复杂度:O(1)——辅助空间个数为常数个
——递归法
int main()
{
int fib(int n);
printf("%d", fib(5));//1 1 2 3 5 8 13 21 34
system("pause");
return 0;
}
int fib(int n)
{
if (n <= 2)
{
return 1;
}
else
return fib(n - 1) + fib(n - 2);
}
//时间复杂度:O(2^n)
//空间复杂度:O(n)
2.二分查找
——迭代算法:
int main()
{
int ret = -1;
int a[] = { 1,2,3,4,5,6,7,8,9};
int len = (sizeof(a) / sizeof(a[0]));
int key = 8;
int left = 0;
int right = len - 1;
int middle = (left + right) / 2;
int middle = (left + right) >>2;(用移位符替代乘除2)
int middle = left + ((right - left) >> 2);
while (left <= right)
{
if (key < middle)
{
right--;
}
else if (key > middle)
{
left++;
}
else
{
return middle;
}
}
printf("%d查找成功", key);
system("pause");
return ret;
}
//时间复杂度:O(log2N)——循环次数为log2N次
//空间复杂度:O(1)——辅助空间个数为常数个
——递归算法:
int binarysearch(int a[], int key, int left, int right)
{
int ret = -1;
int middle = left + ((right - left) >> 2);
while (left <= right)
{
if (key < middle)
return binarysearch(a, key, left, middle - 1);
else if (key > middle)
return binarysearch(a, key, middle + 1, right);
else
return middle;
}
return -1;
}
int main()
{
int key = 2;
int binarysearch(int a[], int key, int left, int right);
int a[] = { 1,2,3,4,5,6 };
printf("%d 成功",key);
system("pause");
return 0;
}
//时间复杂度:O(log2N)——循环次数log2N次
//空间复杂度:O(log2N)——单次所需辅助空间个数常数个。