递归算法的一般形式是:
if(满足边界条件)
return 终止递归时的返回值;
else
return 递归表达式;
这是递归的一般形式,诸如这个的例子,很简单,比如求阶乘
if(n == 1)
return 1; //边界条件时,问题规模为1,此时返回1;
else
return n*f(n-1);//否则递归
它的变体如,在二叉树的寻找parent的一个算法中:
template <class T>
BinTreeNode<T> *BinaryTree<T>::Parent(BinTreeNode<T> *subTree, BinTreeNode<T> *current){
if(subTree == NULL) return NULL;
if(subTree->leftChild == current || subTree->rightChild == current)
return subTree;
BinTreeNode<T> *p;
if(p = (Parent(subTree->leftChild, current)) != NULL)
return p;
else
return Parent(subTree->rightChild, current);
};
我们看这段代码,与上面的异同点是:
1.相同的是,都有边界条件,这里是,考虑仅有三个节点,即一个双亲节点和两个孩子时,是边界条件,返回这个双亲。
都有递归表达式,这里是直接调用自身。
2.不同的是,边界条件个数不同,这里两个边界;
递归表达式个数不同,而且返回哪一个需要进行选择。
所以我们可以看到,递归设计的核心是不变的,但是具体问题还要具体分析,但要抓住内核。
我们来分析不同之处,对于这个特例,这里之所以比一般形式的递归设计多出一些部分的原因如下:
1.无法保证在仅有三个节点时能够找到合适的双亲节点;
2.这个树形结构,它有两个分支,每个分支都是递归的;
所以一般的来讲,我认为可以这样的来设计递归算法:
1.明确递归函数所有可能的结果,推出产生这些结果时的边界条件;
(例如这里,结果有二,一是找到双亲,二是没有找到双亲。第一个的边界条件时三节点并且根是双亲;第二个是当前传入的根节点已经为空)
2.明确调用递归表达式的分支个数,确定返回唯一合适的递归表达式的判断条件;
(例如这里,分支有二,判断条件是哪个不为空返回哪个)
3.根据最一般的递归设计形式,结合上述分析的结果,扩展成针对此特例的递归函数。
(例如这里,边界条件增加1个,返回递归式增加1个并增加判断)。
这是现在的思考结果,本人仅大二,刚学数据结构,水平有限,不足之处请各位前辈指教。