前言
前面给大家提到了有这么一种排序算法既能加快速度也能节约内存,但是呢,这种算法要真正去理解透彻却不是那么容易,这里就需要用到一种数学思维--递归。那么这一篇是讲递归吗,恐怕让大家失望了,因为要想真正去理解递归这个概念也是有点难度的,有的人说递归很简单啊,我平时写一些程序也用到了,可是呢,话不要说太早,你可以看看后面我将写的递归系列再说,既然是系列,姑且打算写四篇关于递归的,下个星期会将递归和那个高效的排序算法一并给出。这一篇将给大家介绍的是一种数学方法--数学归纳法。这个大家应该挺熟悉吧,毕竟高考大题就需要它。这也间接说明了一点,想学好编程,数学也不能太差哦。
正文
言归正传,首先呢给大家介绍一下什么是数学归纳法,用通俗的话讲呢,数学归纳法就是通过特殊的情况推导出一般情况的结果。举个例子:我们都知道 4 > 3
,这可以理解为 3+1 > 3
。那么通过这样一个特殊的情况我们可以推导出,对于给定的任意一个数 n , n+1 > n
成立。
有的人可能会说这不是显而易见的吗,还需要推导吗。那么仔细想一下我们对于这些显而易见的结果其实也有自己的思考,首先你是根据了一个给定的结果,进而去得出了一般的结论。只是很多情况下我们忽略了推导的过程罢了。根据这个例子,想必大家对于数学归纳法有了比较清晰的认识了,就是把很多我们觉得理所当然的结论用比较规范的语言去表达出来。下面给出数学归纳法的规范表达。
步骤一:
证明 “ P(0) 成立 ” //也就是我们上面说的 4 > 3 成立
步骤二:
证明 “ 无论 k 为 0 以上的哪个整数,若 p(k) 成立,则 P(k+1) 也成立 ”
对于这个过程有点人可能要问,我们需要证明的就是 P(k) 成立,假设它成立了,那我们还怎么证明呢。这里就是陷入了一个误区了,这就可以比喻成程序中的局部变量和全局变量了。比如我们有一个局部变量 k ,和一个全局变量 k ,我们应该知道在一个函数块内局部变量是优先调用的,通过局部变量我们定义函数再通过这个函数去求得全局变量需要求出的值,这不是和数学归纳法有些相似吗。
下面给出一个数学例子再次熟悉一下数学归纳法的使用
请证明以下断言 Q(n) 对于 1 以上的所有整数 n 都成立。
断言 Q(n) : 1 + 3 + 5 + 7 + ··· + (2 x n-1) = n2
根据我们上面的归纳,第一步先证明 Q(0) 成立,当然这里第一项为 1,所以先证明 Q(1)
Q(1) = 1 = 12
第二步,假设 Q(k) 成立,即
Q(k) = 1 + 3 + 5 + 7 + ··· + (2 x k-1) = k2
Q(k+1)
= 1 + 3 + 5 + 7 + ··· + (2 x k-1) + (2 x (k-1) -1)
= Q(k) + (2 x (k-1) -1)
= k2 + (2 x (k-1) -1)
= k2 + 2 x k + 1
= (k+1)2
由此可得 Q(n) 成立。
经过这一个例子,我想对于数学归纳法应该有了基本的了解了。既然是计算机专业的学生,我想与编程打交道是不可避免的下面让我们用程序来进一步了解吧。当然这里还是用 C 语言。
#include<stdio.h>
void prove(int n);
int main()
{
int n = 10;//因为程序的限制,只是给定一个具体数据。
prove(10);
getchar();
return 0;
}
void prove(int n)
{
int k;
printf("现在开始证明 P(%d) 成立。\n",n);
k = 0;
printf("根据步骤 1 得出 P(%d) 成立。\n",k);
while(k < n)
{
printf("根据步骤 2 可以说 “若 P(%d) 成立,则 P(%d) 也成立”。\n",k,k+1);
printf("因此可以说 “P(%d) 是成立的”。\n",k+1);
k = k + 1;
}
printf("证明结束。\n");
}

通过这个简单程序,我想大家应该理解的更深刻一点了吧。
最后说一点,个人认为递归其实是跟数学归纳法有些相似的,都是把复杂的问题简单化了,只不过递归是由多变少,数学归纳法由少变多罢了。下个星期正式步入递归,让我们一起期待这种神奇的数学方法吧。
网友评论