1. 递归排序题
通过递归算法来获取一个数组中的最大值
2. 算法思路
采用递归的思路来进行解题,那么肯定是需要自己调用自己的,这也就是递归,于是考虑怎么自己调用自己呢?我们可以采用二分法来制造递归的情况:
我们先取数组的下标中点,将数组分成两份,我们要一直分下去,直到每个单个元素全部出现,这个时候来比较其大小,并往上将最大值赋值给上级根节点,上级根节点和另外一个根节点比较,再传值…
3. 算法程序及注释
class Program
{
static void Main(string[] args)
{
int[] t = { 3, 2, 1, 7, 8, 9, 0 };
var m = GetMax.getMax(t);
Console.WriteLine(m);
Console.ReadLine();
}
}
class GetMax
{
//方便调用
public static int getMax(int[] arr)
{
return process(arr, 0, arr.Length - 1);
}
//arr[L..R]范围求最大值
public static int process(int[] arr, int L, int R)
{
//到最后一个点时,返回他到上一级
if (L == R)
{
return arr[L];
}
//这一段是为了展现递归时的值
//for (int i = L; i <= R; i++)
//{
// Console.WriteLine(arr[i]);
//}
int mid = L + ((R - L) >> 1);//中点,这样写是比较讲究的写法,拿右移位的位运算来代替除以2的操作,原因是位运算比较快
//另外,一般平均值是这样(b+a)/2,但是b+a可能会溢出数据类型的最大范围,所以我们不这样写
int leftMax = process(arr, L, mid);//取左边最大值,来递归一次
int rightMax = process(arr, mid + 1, R);//取右边最大值,来递归一次
return Math.Max(leftMax, rightMax);//最终比较叶节点,值给根节点
}
}
理解程序的流程图:
4. 递归的时间复杂度与master公式
怎么来对递归行为的时间复杂度来进行估算?
使用master公式(也称主方法)(对于一些特定的递归行为而言),是用来利用分治策略来解决问题经常使用的时间复杂度的分析方法
公式:
T(N)=a*T(N/b)+O(N^d)
使用条件:
1.里面递归的子项必须相同
2.n表示问题的规模
3.a是多少个相同的子项,表示递归的次数也就是生成的子问题数
4.(N/b)是说,把一个整的分了多少份,b表示每次递归是原来的1/b之一个规模
5.d指是,剩下的项是多少时间复杂度
举例来说,把一个数组分成了3份来递归,并逐次打印一遍数,那么我们发现子项都是1/3,符合第一个条件(递归的子项必须相同),于是a=3,N/b=1/3N,剩下的时间复杂度(逐次打印一遍数)是O(N),那么d=1的(因为O(N^d)=O(N))
也就是:T(N)=3*T(N/3)+O(N)
然后把a,b,d来进行下面结论的比较,发现符合等于的情况,那么该递归时间复杂度是O(N * logN)
结论:
注: log(b,a)也就是以b为底,a的对数
- log(b,a)>d =>复杂度为O(N^log(b,a))
- log(b,a)<d =>复杂度为O(N^d)
- log(b,a)=d =>复杂度为O(N^d * logN)