算法
解决特定问题求解步骤的描述。在计算机中表现为指令的有限序列,每条指令可表示一个或多个操作。
此外,一个算法还具有下列5个特性:有穷性,确定性,可行性,输入,输出。
算法设计的要求:正确性,可读性,健壮性,效率与低存储量需求。
算法复杂度
- What?时间复杂度和空间复杂度
- Why?可以用度量算法的好与坏
- How?控制变化因素,估算N趋于无穷的复杂度
时间复杂度
- 时间复杂度实际上就是一个计算执行基本操作次数的函数,不受外界影响。
- 方法:大O渐进表示法:一个算法语句总的执行次数是关于问题规模N的某个函数,记为f(N),N称为问题的规模。语句总的执行次数为T(N),当N不断变化时,T(N)也在变化,算法执行次数的增长速率和f(N)的增长速率相同。则有T(N)=O(f(N)),称O(f(n))为时间复杂度的O渐进表示法。
- 常见的时间复杂度:
void Test(int n)
{
int iCount = 0;//1次
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; ++j)
{
iCount++;//1*n*n次
}
}
for (int k = 0; k < 2 * n; k++){
iCount++;//(2*n)次
}
int count = 10;//(1次)
while (count--)//(10次)
{
iCount++;
}
}
//语句总执行次数:f(n)=n*n+2*n+10
//则时间复杂度估算为:O(N*N)
//二分查找
int Binarysearch(int arr[],int sz,int n)
{
int left=0;
int right = sz - 1;
/*int mid = left+(right-left)/2;*/
int mid = left+((right-left)>>1);
//每次比较都除以2
//n=log(N)
//时间复杂度为O(logN)
while (left <= right)
{
if (arr[mid] == n)
{
return mid;
}
else if (arr[mid] > n)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
//递归算法
//求1+2+...+N之和
long sum(int N)
{
if (N == 1)
return 1;
long sum_1 = sum(N - 1);
long retval = sum_1 + N;
return retval;
//return N+sum(N-1);
}
//求阶乘
long long fac(int N)
{
if (N == 1)
return 1;
long long sum_1 = sum(N - 1);
long long retval = sum_1 * N;
return retval;
//return N*sum(N-1);
}
//时间复杂度都为O(N)
总结:
- 找次数;
- O();
- 用常数1取代运行时间中所有加法常数;
- 保留最高阶;
- 若最高阶不是1,则去掉1(即常数)。
空间复杂度
函数中创建对象的个数关于问题规模的函数表达式。相当于求高度,一般用O渐进法表示。
//1.求前n项和
//空间复杂度O(1)
int sum(int n)
{
int count = 0;
for (int i = 0; i < n; i++)
count += i;
return count;
}
//2.斐波那契
//空间复杂度:O(n)
//时间复杂度:O(2^n)
long long Fib(int n)
{
if (n < 3)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
//求兔子个数问题
//空间复杂度:O(n)
//时间复杂度:O(2^n)
long Fib(long first,long second,long n)
{
if (n < 3)
return 1;
if(n==3)
return first+second;
return Fib(second,first+second,n-1);
}