使用递归的四个法则:
1.基准情形(Base case):必须总有某种基准情形,它无须递归就能解出.
2.不断推进(Making progress):对于那些需要递归求解的情形,每一次递归调用都必须要使求解状况朝接近基准的情形的方向推进.
3.设计法则:假设所有的递归调用都能运行.
4.合成效益法则:在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作.
关于算法运行时间的几个法则:
法则1-For 循环:
一次For循环的运行时间至多是该For循环内语句(包括测试)的运行时间乘迭代的次数.
example 01 O(N):
for(int i=0;i<n;i++)
printf("%d",i);
法则2-嵌套的For循环:
从里向外分析这些循环,在一组嵌套循环内部的一条语句的运行时间为该语句的运行时间乘以该组所有的for循环的大小的乘积.
example 02 O(N2):
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
printf("%d",j)
法则3-顺序语句:
将各个语句的运行时间求和即可(这意味着,其中最大的值就是所得的运行时间)
example 03 O(N2)
for(i=0;i<n;i++)
a[i]=i;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i]+=a[j]+1
法则4-IF ELSE语句:
一个IF/ELSE语句的运行时间从不超过判断再加上S1和S2中运行时间长者的总的运行时间.
if(Condition )
S1
else
S2
两个递归的漂亮应用:
1. 最大子序列和问题:O(NlogN)
static int MaxSubSum(const int a[],int Left,int Right)
{
int MaxLeftSum,MaxRightSum;
int MaxLeftBorderSum,MaxRightBorderSum;
int LeftBorderSum,RightBorderSum;
int Center,i;
//Base case
if(Left == Right)
if(a[left]>0)
return a[left];
else
return 0;
Center = (Left + Right)/2;
MaxLeftSum = MaxSubSum(a[],Left,Center);
MaxRightSum = MaxSubSum(a[],Center+1,Right);
MaxLeftBorderSum = 0; LeftBorderSum =0;
for(i=Center;i>=Left;i--)
{
LeftBorderSum +=a[i];
if(LeftBorderSum >MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}
MaxRightBorderSum = 0;RightBorderSum =0;
for(i=Center+1;i<=Right;i++)
{
RightBorderSum +=a[i];
if(RightBorderSum>MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}
return Max3(MaxRightSum,MaxLeftSum,MaxLeftBorderSum+MaxRightBorderSum);
}
int MaxSubsqeenceSum(const int a[],int n)
{
return MaxSubSum(a,0,n-1);
}
2. 幂运算:O(logN)
long int Pow(long int x,int n)
{
//Base case
if(n=0)
return 1;
if(n=1)
return n;
if(IsEven(N))
return Pow(x*x,n/2);
else
return Pow(x,n-1)*x;
}
两个经典算法:
1.二分查找:O(logN)
int BinarySearch(const ElementType a[],Element x,int n)
{
int low,mid,high;
low =0;high = n-1;
while(low<=high)
{
mid=(high-low)/2;
if(a[mid] > x)
low = mid+1;
else
if(a[mid]<x)
high = mid-1;
else
return mid;
}
return -1;
}
2.欧几德时算法,求两个数的最多公因数Gcd: O(logN)
int Gcd(int m,int n)
{
int rem;
while(n>0)
{
rem = m%n;
m=n;
n=rem;
}
return m;
}