程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
一.累加
#include <stdio.h>
int addTo(int paraN) {
int tempSum;
printf("entering addTo(%d)\r\n", paraN);
if (paraN <= 0) {
printf(" return 0\r\n");
return 0;
} else {
tempSum = addTo(paraN - 1) + paraN;
printf(" return %d\r\n", tempSum);
return tempSum;
}
}
void addToTest() {
int n, sum;
printf("---- addToTest begins. ----\r\n");
n = 5;
sum = addTo(n);
printf("\r\n0 adds to %d gets %d.\r\n", n, sum);
n = 1;
sum = addTo(n);
printf("\r\n0 adds to %d gets %d.\r\n", n, sum);
n = -1;
sum = addTo(n);
printf("\r\n0 adds to %d gets %d.\r\n", n, sum);
printf("---- addToTest ends. ----\r\n");
}// Of addToTest
/**
The entrance.
*/
int main() {
addToTest();
}// Of main
以计算5的累加为例,将起拆解为4的累加+5,4的累加又可以拆为3的累加加4.....直到0的累加为0,开始返回函数值,进而得到1的累加,2的累加,最后得到5的累加。
运行结果:
二.汉诺塔问题
相传在古印度圣庙中,有一种被称为汉诺塔的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
64个盘太复杂,思考的时候我们可以首先思考只有两个盘的情况,我们只需要进行操作A->B,A->C,B->C即可实现,现在不管最低盘上面有几个盘,以63个盘为例,我们都可以这样简化,把底盘上面63个盘从A杆移到B杆,把最低盘移到C杆,再把63个盘从B杆移到C杆,此时A为起始杆,B为转移杆,C为目标杆),那如何把63个盘从a杆移到b杆呢,我们可以把63个盘拆为上面62个盘和最底下的盘,只要把62盘先移到c杆,把最底下的盘移到b杆,再把62个盘移到b杆就实现了(此时A为起始杆,C为转移杆,B为目标杆),62个盘又能继续拆分......直到拆分成1个盘的操作,再层层返回最终实现64个盘的操作。
我认为汉诺塔问题比累加问题难理解的多是因为思考问题的过程中要考虑目标杆,转移杆,起始杆的不断变换,但是不管再怎么变化,每层递归都能简化为将除底盘以外的盘从起始杆移动到转移杆,将底盘移动到目标杆,最终将除底盘以外的盘移动到目标杆
因此我们可以考虑以起始杆、转移杆,目标杆为变量的函数,同时设计函数的时候,我认为只要以一层为参考就行了,考虑多层很有可能把自己绕进去
下面是函数进行的操作
void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit) {
if (paraN <= 0) {
return;
} else {
hanoi(paraN - 1, paraSource, paraTransit, paraDestination);
printf("%c -> %c \r\n", paraSource, paraDestination);
hanoi(paraN - 1, paraTransit, paraDestination, paraSource);
}
}
下面是总程序以及运行结果
#include <stdio.h>
void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit) {
if (paraN <= 0) {
return;
} else {
hanoi(paraN - 1, paraSource, paraTransit, paraDestination);
printf("%c -> %c \r\n", paraSource, paraDestination);
hanoi(paraN - 1, paraTransit, paraDestination, paraSource);
}
}
void hanoiTest() {
printf("---- addToTest begins. ----\r\n");
printf("2 plates\r\n");
hanoi(2, 'A', 'C', 'B');
printf("3 plates\r\n");
hanoi(3, 'A', 'C', 'B');
printf("---- addToTest ends. ----\r\n");
}
int main() {
hanoiTest();
return 0;
}