递归和master公式

递归的本质是系统帮我们进行了压栈,栈的名字叫做系统栈。但系统栈的空间十分有限,因此在工程上我们需要把递归改写成用内存中的栈来模拟系统压栈,以此来实现非递归。

master公式又叫主定理,是一种估算递归时间复杂度的公式。但有个前提条件:只有是子问题规模相同的递归才能使用。

T(N) = a * T(N / b)+ O(N ^ c), a 、b 、c都是常数。

a是调用的子问题的次数

b是问题被分为多少个子问题的个数

c是调用之外的时间复杂度

如果logba < c, 复杂度为: (N ^ c)。

如果logba > c, 复杂度为: (N ^ logba)。

如果logba == c, 复杂度为: (N ^ c * logN)。

补充:T(N) = a * T(N / b)+ O(N * logN),时间复杂度是O(N * (logN) ^ 2)。

题目如下:利用分治法求一个数组中的最大值。

code分析

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf 
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 10

int max(int *a, int l, int r)  {
	if (l >= r) {
		return a[l];
	}
	
	int mid = l + ((r - l) >> 1);
	int lMax = max(a, l, mid);
	int rMax = max(a, mid + 1, r);
	
	return lMax > rMax? lMax: rMax;
}

int main(int argc, char* argv[])
{
	int a[N] = {0};
	
	srand(time(0));
	
	fr (i, 0, N) {
		sc("%d", a + i);
	}

	pr("%d", max(a, 0, N - 1));

	
	return 0;
}

那么这个递归可以用master公式吗?很明显是可以的因为,每个子问题都是相同规模的。

那么T(N) = T(N * 1 / 2) + T(N * 1 / 2) + O(1),那么化简一下T(N) = 2 * T(N / 2) + O(N ^ 0)。那么a = 2,b = 2, c = 0。

那么logba > c,所以时间复杂度是O(N ^ logba),因为a = 2, b = 2,所以logba = 1,所以时间复杂度是O(N ^ 1) = O(N)。

那么如果我每次把问题分成求左边2 / 3的最大值和求右边2 / 3的最大值的话,那么还能用master公式吗,也可以因为子问题的规模是相同的,那么时间复杂度就是T(N) = T(N * 2 / 3) + T(N * 2 / 3) + O(1) = 2 * T(N / (3 / 2)) + O(N ^ 0)。那么a = 2, b = 3 / 2, 因为master是除法,所以是倒数关系。

那么如果我每次都要在返回之前都要打印一下我的数组,那时间复杂度是多少呢?

那么很明显是T(N) = 2 * T(N / 2) + O(N ^ 1), 因为除了调用的时间复杂度是O(N),所以是O(N ^ 1)。那么a = 2, b = 2, c = 1。

posted @   lwj1239  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示