二叉树 网易2016实习研发工程师编程题

题目:

有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。

给定二叉树的根节点root,请返回所求距离。

 

这道题注意是最大的叶子节点到最小的叶子节点的距离。叶子节点是没有左右孩子的节点。

  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 #include <queue>
  5 #include <unordered_map>
  6 #include <map>
  7 #include <algorithm>
  8 using namespace std;
  9 
 10 struct TreeNode {
 11     int val;
 12     struct TreeNode *left;
 13     struct TreeNode *right;
 14     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 15 };
 16 
 17 //以前序遍历创建二叉树
 18 void CreateBiTree(TreeNode **T)//*T是指向BiTNode的指针
 19 {
 20     *T=new TreeNode(0);
 21     if(*T==NULL)//如果*T还是指向NULL,表示内存分配失败,退出程序
 22         exit(OVERFLOW);
 23     char ch;
 24     cin>>ch;
 25     if(ch=='#')
 26         *T=NULL;
 27     else
 28     {
 29         (*T)->val=ch-'0';//*T指向的节点的data分配内容,即生成根节点
 30         CreateBiTree(&((*T)->left));//创建&(*T)->lchild临时变量,传入CreateBiTree,构造左子树
 31         CreateBiTree(&((*T)->right));//创建&(*T)->rchild临时变量,传入CreateBiTree,构造右子树
 32     }
 33 }
 34 
 35 /*
 36 分两大步
 37 1 标记每个节点的父节点,并且找出最大叶节点和最小叶节点
 38     用map<int,pair<int,int>>标记每个子节点的父节点,first是子节点值,second是<父节点值,父节点位置>
 39     用queue遍历二叉树的节点
 40     依次把每个父节点的子节点push进队列,每取出一个节点处理,计数加1,然后处理取出节点的左右孩子进行标记
 41     处理完之后,把取出的节点pop出去
 42 2 计算两个叶节点的最短路径
 43     分别找出两个叶节点到树根的路径,公共部分以前的路径相加即最短路径
 44 */
 45 class Tree {
 46 public:
 47     int getDis(TreeNode* root) 
 48     {
 49         // write code here
 50         //第1步
 51         map<int, pair<int, int>> parent;//标记每个子节点的父节点
 52         queue<TreeNode*> que;//按照层序遍历处理每个节点
 53         que.push(root);
 54         parent[root->val] = make_pair(0, 0);//树根的双亲设置为(0,0)
 55         int max = -65535;
 56         int min = 65536;
 57         int cnt = 0;//每处理一个节点计数加1
 58         while (!que.empty())
 59         {
 60             //处理队列里的每个节点,每处理一个,计数加1。即cnt是目前处理的节点的序号(按层序遍历标序)。
 61             TreeNode* temp = que.front();
 62             cnt++;
 63             //处理该节点的左右孩子
 64             if (temp->left)//如果该节点有左孩子,标记左孩子,并且把左孩子入队列
 65             {
 66                 parent[(temp->left)->val] = make_pair(temp->val, cnt);
 67                 que.push(temp->left);
 68             }
 69             if (temp->right)//如果该节点有右孩子,标记右孩子,并且把右孩子入队列
 70             {
 71                 parent[(temp->right)->val] = make_pair(temp->val, cnt);
 72                 que.push(temp->right);
 73             }
 74             if (temp->left == NULL &&temp->right == NULL)//如果该节点是叶子节点,需要比较它和max和min的大小
 75             {
 76                 if (temp->val > max)
 77                     max = temp->val;
 78                 if (temp->val < min)
 79                     min = temp->val;
 80             }
 81             que.pop();
 82         }
 83         //第2步
 84         vector<int> v1;
 85         vector<int> v2;
 86         v1.push_back(min);
 87         v2.push_back(max);
 88         int move1 = min;
 89         int move2 = max;
 90         while(parent[move1].second > 0)//把min到树根的路径找出来
 91         {
 92             v1.push_back(parent[move1].first);
 93             move1 = parent[move1].first;            
 94         }
 95         while (parent[move2].second > 0)//把max到树根的路径找出来
 96         {
 97             v2.push_back(parent[move2].first);
 98             move2 = parent[move2].first;
 99         }
100         //反转一下方便查找公共串,第一个节点都是树根
101         reverse(v1.begin(), v1.end());
102         reverse(v2.begin(), v2.end());
103         int n = 0;
104         for (;v1[n] == v2[n];n++);//n是公共串的结尾            
105         return (v1.size() + v2.size() - 2 * n);                        
106     }
107 };
108 
109 //测试
110 int main()
111 {
112     TreeNode **pp;//定义指向BiTNode的二级指针pp
113     TreeNode *p;//定义指向BiTNode的指针p
114     pp=&p;//pp指向p
115     p=NULL;//初始化p指向NULL
116     CreateBiTree(pp);//传入指向p的地址,创建二叉树,输入5129###3##4#68##7##
117     Tree solution;
118     cout << solution.getDis(p);
119     return 0;
120 }
posted @ 2016-07-29 15:58  Pearl_zju  阅读(861)  评论(0编辑  收藏  举报