码迷,mamicode.com
首页 > 其他好文 > 详细

笔试算法题(36):寻找一棵二叉树中最远节点的距离 & 根据二叉树的前序和后序遍历重建二叉树

时间:2014-05-25 22:23:43      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   c   code   java   

出题:求二叉树中距离最远的两个节点之间的距离,此处的距离定义为节点之间相隔的边数;

分析:

  • 最远距离maxDis可能并不经过树的root节点,而树中的每一个节点都可能成为最远距离经过的子树的根节点;所以计算出以每个节点为根节点的子树的最 远距离,最后取他们的最大值就是整棵树的最远距离;
  • 如果递归层次过多造成系统栈溢出,则可以使用stack堆栈结构存储递归节点,从而使用循环实现

解题:

bubuko.com,布布扣
 1 struct Node {
 2         int value;
 3         Node *left;
 4         Node *right;
 5         int leftDis;
 6         int rightDis;
 7 };
 8 
 9 void MaxDistance(Node *root, int *MaxDis) {
10         /**
11          * 三个递归停止条件
12          * */
13         if(root==NULL)
14                 return;
15         if(root->left==NULL)
16                 root->leftDis=0;
17         if(root->right==NULL)
18                 root->rightDis=0;
19 
20         /**
21          * 处理当前节点之前,首先处理子节点
22          * */
23         if(root->left!=NULL)
24                 MaxDistance(root->left, MaxDis);
25         if(root->right!=NULL)
26                 MaxDistance(root->right, MaxDis);
27 
28         /**
29          * 递归仅处理了root->left和root->right为根节点的
30          * 最远距离,所以当前已经知道root->left和root->right
31          * 各自的leftDis和rightDis
32          * */
33         if(root->left!=NULL) {
34                 int tempMax=0;
35                 if(root->left->leftDis > root->left->rightDis)
36                         tempMax=root->left->leftDis;
37                 else
38                         tempMax=root->left->rightDis;
39                 root->leftDis=tempMax+1;
40         }
41         if(root->right!=NULL) {
42                 int tempMax=0;
43                 if(root->right->leftDis > root->right->rightDis)
44                         tempMax=root->right->leftDis;
45                 else
46                         tempMax=root->right->rightDis;
47                 root->rightDis=tempMax+1;
48         }
49         /**
50          * 更新全局的最远距离MaxDis,最初调用的时候需要赋值为-1
51          * */
52         if(*MaxDis < root->leftDis + root->rightDis)
53                 *MaxDis=root->leftDis + root->rightDis;
54 }
bubuko.com,布布扣

 

出题:如果已经知道一棵二叉树的前序和中序遍历结果,如何快速重建二叉树。如果知道前序和后序,或者知道中序和后序,是否仍旧可以重建;

分析:

  • 下述为一个二叉树的例子,对应的前序,中序和后序遍历如下:

    Pre: abdehcfgi

    In: dbehafcig

    Suffix: dhebfigca

bubuko.com,布布扣
  • 如果仅知道Pre和In,Pre序列的第一个字符必定为当前子树的根节点(a),所以对应到In序列中,可以根节点为分界(a)将左右子树分开(dbeh 和fcig),然后递归直到仅剩下一个字符;
  • Suffic和In也同理,但是仅知道Pre和Suffix不能重建二叉树。

解题:

bubuko.com,布布扣
 1 struct Node {
 2         int value;
 3         Node *left;
 4         Node *right;
 5 };
 6 
 7 Node* RestoreTree(char *pre, int pre1, int pre2,
 8                                                 char *in, int in1, int in2) {
 9         if(pre1>pre2 || in1>in2) return NULL;
10         /**
11          * 当前pre的第一个字符必定是一棵子树的根节点
12          * 所以首先创建一个节点
13          * */
14         Node *temp=new Node();
15         temp->value=pre[pre1];
16         temp->left=NULL;
17         temp->right=NULL;
18 
19         /**
20          * 当pre1和pre2相等时,说明已经只有一个字符
21          * 则说明二叉树已经到达子节点,直接返回
22          * */
23 
24         if(pre1==pre2 || in1==in2)
25                 return temp;
26 
27         /**
28          * 查找pre[pre1]在in序列中的位置
29          * */
30         int i;
31         for(i=in1;i<=in2;i++) {
32                 if(pre[pre1]==in[i])
33                         break;
34         }
35 
36         /**
37          * 对pre和in序列进行划分,注意当一个节点仅有左子节点
38          * 或者只有右子节点时,pre1可能大于pre2
39          * */
40         temp->left=RestoreTree(pre, pre1+1, pre1+(i-in1),
41                                                         in, in1, i-1);
42         temp->right=RestoreTree(pre, pre1+(i-in1)+1, pre2,
43                                                         in, i+1, in2);
44 
45         return temp;
46 }
47 
48 void showTree(Node *root) {
49         if(root==NULL)
50                 return;
51 
52         if(root->left!=NULL && root->right!=NULL) {
53                 printf("%c, %c\n",root->left->value,
54                                                 root->right->value);
55                 showTree(root->left);
56                 showTree(root->right);
57         } else if(root->left!=NULL) {
58                 printf("%c\n",root->left->value);
59                 showTree(root->left);
60         } else if(root->right!=NULL) {
61                 printf("%c\n",root->right->value);
62                 showTree(root->right);
63         }
64 }
65 
66 int main() {
67         char pre[]="abdehcfgi";
68         char in[]="dbehafcig";
69 
70         Node *root=RestoreTree(pre, 0, 8, in, 0, 8);
71         showTree(root);
72         return 0;
73 }
bubuko.com,布布扣

 

笔试算法题(36):寻找一棵二叉树中最远节点的距离 & 根据二叉树的前序和后序遍历重建二叉树,布布扣,bubuko.com

笔试算法题(36):寻找一棵二叉树中最远节点的距离 & 根据二叉树的前序和后序遍历重建二叉树

标签:style   class   blog   c   code   java   

原文地址:http://www.cnblogs.com/leo-chen-2014/p/3751182.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!