看了几天代码之后,发现一个难题---->递归!
总感觉自己思考方法有极大的缺陷,无奈本人愚钝,只能抱大腿,特记录下来与大家分享,共勉~
1、递归的设计思想:递归其实就是把一个问题 A 拆成子问题 A1,A2,..AN,对于最简单的一种情况就是 A1,A2,...AN 与问题 A 相似,不过问题的规模当然会更小,这样的话,如果你已经知道要怎么解决A1,A2,...AN 了,那么就能够解决 A;
举个栗子:
int f(int N) {
if( N<=2 ) return N;
return f(N-1)+f(N-2);
}
这段代码的意思是, f(N) =f(N-1)+f(N-2),且 f(1)=1, f(2)=2;所以就是个斐波那契数列
2、
错误方法:对循环比较熟悉,对递归陌生,总是喜欢把函数循环代进去 就把自己绕晕~
就上面那个例子,在计算 f(N) 时,假定已经知道了 f(N-1) 和 f(N-2) 的值,那么 f(N)=f(N-1)+f(N-2)就可以求出 f(N) 了;
然而发现 f(N-1) 的值其实并不知道,不过没关系,我就假定我已经知道了 f(N-2) 和 f(N-3) 的值,好了,现在可以求出 f(N-1)了,
类似地,不断重复这个过程,在计算 f(1) 和 f(2) 时发现这两个的值是已知的,这个就是递归的终止条件。
3、把刚刚思维过程运用到其他函数中,举个稍微复杂一点的
例子,就
剑指offer的26题。
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree == NULL)
return NULL;
TreeNode *nodeList = NULL;
ConvertNode(pRootOfTree, &nodeList);
TreeNode *headList = nodeList;
while(headList->left != NULL)
headList = headList->left;
return headList;
}
void ConvertNode(TreeNode *RootOfTree, TreeNode **nodeList){
TreeNode *Current = RootOfTree;
if(Current->left != NULL)//遍历左子树
ConvertNode(Current->left, nodeList);
Current->left = *nodeList;
if(*nodeList != NULL)//把左孩子改为先继节点
(*nodeList)->right = Current;
*nodeList = Current;
if(Current->right != NULL)//遍历右子树
ConvertNode(Current->right, nodeList);
}
};
一棵二叉树是由 根节点+左子树+右子树构成的,于是我就认为我的 左子树已经转化成链表了,所以我只要简单的将当前节点加在末尾就好了,然后我认为右子树也已经转化成链表了,所以让把右子树的根节点(当前根节点的右孩子)当作我的后继节点就好了。