主1:关于递归算的证明是证明算法的正确性。
证明所需工具:数学归纳法。
证明分为两个步骤:
1、证明该算法对于任意有意义的输入都可以返回。
2、证明该算法对于任意有意义的输入它的返回都是正确的。
总结,对于任意有意义的输入都可以返回正确的结果。
例子:Hanoi(汉诺)塔问题:
void hanoi(int n,char s,char t,char d) // s=source t=temporary d=destination
{
if(1 == n) // 程序段一
{
printf("%c -> %c\n",s,d); // move s to d
}
else // 程序段二
{
hanoi(n-1,s,d,t);
printf("%c -> %c\n",s,d); // move s to d
hanoi(n-1,t,s,d);
}
}
hanoi(n,'1','2','3'); // 初始调用
对于初始调用第2、3、4参数都是固定的,因此我们只对第一个参数n进行归纳。
第一步:
当 n = 1 时,该函数进入程序段一,打印 1 -> 3 后就返回了,因此该函数可以返回。
假设:当 n = k-1 >= 1 时该函数可以返回。
当n = k时,初始调用进入程序段二(n显然大于1)
调用hanoi(k-1,s,d,t),根据假设该函数可以返回,
打印一段话,
调用hanoi(k-1,t,s,d),根据假设该函数可以返回,
最终返回。
因此根据初始条件和归纳该函数对于任意有意义的输入都可以返回。
第二步:
当 n = 1 时,该函数进入程序段一,打印 1 -> 3 ,然后直接返回了,因此该函数显然正确。
假设:当 n = k – 1 >= 1 时该函数可以返回正确的结果。
当 n = k 时,初始调用进入程序段二
调用hanoi(k-1,s,d,t),根据假设该函数可以返回正确的结果,即它可以将柱子s(初始调用的s = ‘1’)上k-1个 盘子借助柱子d移动到柱子t上,
此时柱子s上只有一个盘子了(且是那个最大的盘子),且d上没有盘子,因此可以将柱子s上的那个盘子移动到柱子d上(printf(“%c -> %c\n”,s,d); )。
调用hanoi(k-1,t,s,d),根据假设该函数可以返回正确的结果,即它可以将柱子t上的k-1个盘子借助柱子s移动到柱子d上,
至此,所有的盘子已经从柱子s移动到柱子d上了。
总结:该函数对于任意有意义的输入都可以返回正确的结果。
证毕!
设计阶段:
……