二叉树学习


二叉树的递归思想是一大难点。自认为是容易遗忘的东西。

简单问题:

求n!, result = n*(n-1)*(n-2)......1

自然循环可以解决问题
  1. int i,result;
  2. result = n;
  3. for (i=n-1; i>0; i--)
  4. {
  5.   result *= n;
  6. }
递归的写法就是:

  1. int fibonacci1(int n)
  2. {
  3.     if (n == 1)
  4.         return 1;
  5.     else
  6.     {
  7.         return n*fibonacci1(n-1);
  8.     }
  9. }
很明显的特点是:
1.有一个退出函数的条件.
2.重复调用自身,并每次变化参数.

这里如果n == 1,就不再调用自身,直接return;否则将n-1作为参数继续调用自身。

数学的表达式应该是:

f(n) = n*f(n-1) = n*(n-1)*f(n-2) = n*(n-1)*(n-2)*....*1;

程序的理解:

调用f(6)
return 6*f(5)  ---> 调用f(5)
          ^-------  return 5*f(4) ----> 调用f(4)
                              ^-------- return 4*f(3) ----> 调用f(3)
                                                  ^-------- return 3*f(2) -----> 调用f(2)
                                                                       ^--------  return 2*f(1) ----> 调用f(1)
                                                                                            ^-------return 1;
                     
整个过程就是这样的,因为函数调用会出现新的堆栈,返回再恢复堆栈,效率没有非递归高(我知道但感受不到^_^).

二叉树的建立:

定义:

  1. typedef struct Node
  2. {
  3.     int data;
  4.     struct Node *lChild; //左孩子
  5.     struct Node *rChild; //右孩子
  6. }Node, *PNode;
创建:
  1. void create(PNode &T)
  2. {
  3.     int d;
  4.     T = NULL;
  5.     scanf("/n%d", &d);
  6.     if (d == -1)
  7.         T = NULL;
  8.     else
  9.     {
  10.         T = (PNode)malloc(sizeof(Node));
  11.         assert(T);
  12.         T->data = d;
  13.         create(T->lChild);
  14.         create(T->rChild);
  15.     }
  16. }
注意create函数的参数,可以参看本blog的两种传递地址方法
http://blog.youkuaiyun.com/gnuser/archive/2008/09/23/2968136.aspx

调用方法:

  1. int _tmain(int argc, _TCHAR* argv[])
  2. {
  3.     PNode root = NULL;
  4.     create(root);
  5.     return 0;
  6. }
输入顺序:
1
2
3
-1
-1
4
-1
-1
5
-1
-1

过程如下:
create(root)
d = 1      -> root = 新节点
                root->data = d;
                create(root->lChild); -> d=2; 
                create(root->rChild);    root->lChild = 新节点
                                         root->lChild->data = d;
                                         create(root->lChild->lChild); -> d=3;
                                         create(root->lChild->rChild);    root->lChild->lChild = 新节点
                                                                          root->lChild->->lChild->data = d;
                                                                  create(root->lChild->lChild->lChild);
                                                                  create(root->lChild->lChild->rChild);

从这里
d=-1;
root->lChild->lChild->lChild = NULL;
函数就开始回溯,返回到调用函数的下一条语句,然后再根据输入判断是否继续构造上一树节点的右树,如果右树还有左树的话将继续递归,直到回溯完成,调试一下可能更清楚点。

ok,有机会画个流程图就更清楚了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值