微软100题第11题

参照:http://blog.csdn.net/caryaliu/article/details/8107089

参照:http://blog.csdn.net/lalor/article/details/7626678

把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两个节点之间的个数。

写一个程序求一棵二叉树中相距最远的两个节点之间的距离。

如下图所示,粗箭头的边表示最长距离:


树中相距最远的两个节点是A, B

分析可知:对于二叉树,若要两个节点U,V相距最远,有两种情况:

1,从U节点到V节点之间的路径经过根节点

2,从U节点到V节点之间的路径不经过根节点,这种情况下,U,V节点必定在根节点的左子树或者右子树上,这样就转化为求以根节点的孩子节点为根节点的二叉树中最远的两个节点间的距离

上面所说的经过根节点,是指路径中包含根节点,例如:加入上图中只有左子树FGHA, 那么最长距离的两个节点是F, A,该路径中包含根节点F,也称为经过根节点。

于是我们可以递归求解,按照二叉树的中序遍历方式遍历二叉树,在遍历的过程中寻找相距最远的两个节点。

解法1:

  1. #include <iostream>  
  2. #include <stdlib.h>  
  3. using namespace std;  
  4.   
  5. struct BinaryTreeNode   
  6. {  
  7.     int m_nValue;  
  8.     struct BinaryTreeNode *m_pLeft;  
  9.     struct BinaryTreeNode *m_pRight;  
  10. };  
  11.   
  12. int maxDistance(BinaryTreeNode *root, int *max);  
  13. int DistanceCore(BinaryTreeNode *root,int *max);  
  14. //后序遍历,用于我们建立的二叉树是否正确  
  15. void Traverse( BinaryTreeNode * root);  
  16. BinaryTreeNode* Construct(int *preorder, int *inorder, int lenght);  
  17. BinaryTreeNode* ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder);  
  18. int InsertNodeAtMostRight(BinaryTreeNode * root, BinaryTreeNode * node);  
  19.   
  20.   
  21. int main(int argc, char* argv[])  
  22. {  
  23.   
  24.     int preOrder[] = {5, 4, 8, 9, 6, 3, 18, 19, 2};  
  25.     int inOrder[] = {9, 8, 6, 3, 4, 5, 19, 18, 2};  
  26.   
  27.     int max;  
  28.   
  29.     //建树  
  30.     BinaryTreeNode *parent = Construct(preOrder, inOrder, sizeof(inOrder) / sizeof(inOrder[0]));  
  31.   
  32.     cout << "A树的后序遍历的结果:" << endl;  
  33.     Traverse(parent);  
  34.     cout << endl;  
  35.   
  36.     BinaryTreeNode *node1 = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));  
  37.     BinaryTreeNode *node2 = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));  
  38.   
  39.     node1->m_nValue = 0;  
  40.     node1->m_pLeft = NULL;  
  41.     node1->m_pRight = NULL;  
  42.   
  43.     node2->m_nValue = 0;  
  44.     node2->m_pLeft = NULL;  
  45.     node2->m_pRight = NULL;  
  46.   
  47.     maxDistance(parent, &max);  
  48.     cout <<"max distance of tree's nodes : " << max << endl;  
  49.   
  50.     InsertNodeAtMostRight(parent, node1);  
  51.     maxDistance(parent, &max);  
  52.     cout <<"max distance of tree's nodes after insert node1: " << max << endl;  
  53.   
  54.     InsertNodeAtMostRight(parent, node2);  
  55.     maxDistance(parent, &max);  
  56.     cout <<"max distance of tree's nodes after insert node2: " << max << endl;  
  57.   
  58.     //测试极端情况,即只有一个节点  
  59.     maxDistance(node2, &max);  
  60.     cout <<"just one node " << max << endl;  
  61.   
  62.     //测试极端情况,即只有二个节点  
  63.     maxDistance(node1, &max);  
  64.     cout <<"just two node " << max << endl;  
  65.     return 0;  
  66. }  
  67.   
  68. BinaryTreeNode* Construct(int *preorder, int *inorder, int lenght)  
  69. {  
  70.     if (preorder == NULL || inorder == NULL || lenght <= 0)   
  71.     {  
  72.         return NULL;  
  73.     }  
  74.     return ConstructCore(preorder, preorder + lenght - 1, inorder, inorder + lenght - 1);  
  75. }  
  76.   
  77. BinaryTreeNode* ConstructCore(int *startPreorder, int *endPreorder, int *startInorder, int *endInorder)  
  78. {  
  79.     int rootValue = startPreorder[0];  
  80.     BinaryTreeNode *root = new BinaryTreeNode();  
  81.     root->m_nValue = rootValue;  
  82.     root->m_pLeft = root->m_pRight = NULL;  
  83.   
  84.     if (startPreorder == endPreorder)   
  85.     {//先序遍历已经结束了,那这个时候一定是插入最后一个节点,则应该满足下面的if语句,否则输入的数据有误  
  86.         if (startInorder == endInorder && *startPreorder == *startInorder)   
  87.         {  
  88.             return root;  
  89.         }  
  90.         else  
  91.         {  
  92.             cout << "Invalid input" << endl;  
  93.             exit(-1);  
  94.         }  
  95.     }  
  96.   
  97.     int *rootInorder = startInorder;  
  98.     while (rootInorder <= endInorder && *rootInorder != rootValue)   
  99.     {  
  100.         ++rootInorder;  
  101.     }  
  102.     if (rootInorder <= endInorder && *rootInorder != rootValue)   
  103.     {  
  104.         cout << "Invalid input" << endl;  
  105.         exit(-1);  
  106.     }  
  107.   
  108.     int leftLength = rootInorder - startInorder;  
  109.     int *leftPreorderEnd = startPreorder + leftLength;  
  110.   
  111.     if (leftLength > 0)   
  112.     {  
  113.         root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd, startInorder, rootInorder - 1);  
  114.     }  
  115.     if (leftLength < endPreorder - startPreorder)   
  116.     {  
  117.         root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder, rootInorder + 1, endInorder);  
  118.     }  
  119.   
  120.     return root;      
  121. }  
  122.   
  123. void Traverse( BinaryTreeNode * root)  
  124. {  
  125.     if (root == NULL)   
  126.     {  
  127.         return;  
  128.     }  
  129.     else  
  130.     {  
  131.         Traverse(root->m_pLeft);  
  132.         Traverse(root->m_pRight);  
  133.         cout << root->m_nValue << "  ";  
  134.     }  
  135. }  
  136. int maxDistance(BinaryTreeNode *root, int *max)  
  137. {  
  138.     //这个函数的主要功能是判断root不为空,且给max赋初值  
  139.     if (root == NULL || max == NULL)   
  140.     {  
  141.         return -1;  
  142.     }  
  143.     *max = 0;  
  144.     return DistanceCore(root, max);  
  145. }  
  146.   
  147. int DistanceCore(BinaryTreeNode *root, int *max)  
  148. {  
  149.     //如果节点是叶子节点,则返回0——深度  
  150.     if (root->m_pLeft == NULL && root->m_pRight == NULL)   
  151.     {  
  152.         return 0;  
  153.     }  
  154.   
  155.     //保存左右子树的最大深度  
  156.     int lDistance = 0;  
  157.     int rDistance = 0;  
  158.   
  159.     //左子树不为空,返回当前节点到左子树的最大深度  
  160.     if (root->m_pLeft != NULL)   
  161.     {  
  162.         lDistance = 1 + DistanceCore(root->m_pLeft, max);  
  163.     }  
  164.   
  165.     if (root->m_pRight != NULL)   
  166.     {  
  167.         rDistance = 1 + DistanceCore(root->m_pRight, max);  
  168.     }  
  169.   
  170.     //遍历到当前节点时,能获得的最大距离  
  171.     if (lDistance + rDistance > *max)   
  172.     {  
  173.         //保存当前获得的最大距离  
  174.         *max = lDistance + rDistance;  
  175.     }  
  176.     //返回左右子树中,深度较大的一个  
  177.     return lDistance > rDistance ? lDistance : rDistance;  
  178. }  
  179.   
  180.   
  181. //为了测试程序写的辅助函数,在树的最最右边插入一个新的节点  
  182. int InsertNodeAtMostRight(BinaryTreeNode * root, BinaryTreeNode * node)  
  183. {  
  184.     if (root == NULL || node == NULL)   
  185.     {  
  186.         return -1;  
  187.     }  
  188.   
  189.     while (root->m_pRight != NULL)   
  190.     {  
  191.         root = root->m_pRight;  
  192.     }  
  193.   
  194.     root->m_pRight = node;  
  195.     return 0;  
  196. }  
解法2:

  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3.   
  4. typedef struct Node {  
  5.     struct Node *pleft;     //左孩子  
  6.     struct Node *pright;    //右孩子  
  7.     char chValue;           //该节点的值  
  8.   
  9.     int leftMaxValue;       //左子树最长距离  
  10.     int rightMaxValue;      //右子树最长距离  
  11. }LNode, *BinTree;  
  12.   
  13. void findMaxLen(BinTree root, int *maxLen) {  
  14.     //遍历到叶子结点,返回  
  15.     if(root == NULL)  
  16.         return;  
  17.   
  18.     //如果左子树为空,那么该节点左边最长距离为0  
  19.     if(root->pleft == NULL)  
  20.         root->leftMaxValue = 0;  
  21.   
  22.     //如果右子树为空,那么该节点右边最长距离为0  
  23.     if(root->pright == NULL)  
  24.         root->rightMaxValue = 0;  
  25.   
  26.     //如果左子树不为空,递归寻找左子树最长距离  
  27.     if(root->pleft != NULL)  
  28.         findMaxLen(root->pleft, maxLen);  
  29.   
  30.     //如果右子树不为空,递归寻找右子树最长距离  
  31.     if(root->pright != NULL)  
  32.         findMaxLen(root->pright, maxLen);  
  33.   
  34.     //计算左子树中距离根节点的最长距离  
  35.     if(root->pleft != NULL) {  
  36.         if(root->pleft->leftMaxValue > root->pleft->rightMaxValue)  
  37.             root->leftMaxValue = root->pleft->leftMaxValue + 1;  
  38.         else  
  39.             root->leftMaxValue = root->pleft->rightMaxValue + 1;  
  40.     }  
  41.   
  42.     //计算右子树中距离根节点的最长距离  
  43.     if(root->pright != NULL) {  
  44.         if(root->pright->leftMaxValue > root->pright->rightMaxValue)  
  45.             root->rightMaxValue = root->pright->leftMaxValue + 1;  
  46.         else  
  47.             root->rightMaxValue = root->pright->rightMaxValue + 1;  
  48.     }  
  49.   
  50.     //更新最长距离  
  51.     if(root->leftMaxValue + root->rightMaxValue > *maxLen)  
  52.         *maxLen = root->leftMaxValue + root->rightMaxValue;  
  53. }  
  54.   
  55. //创建二叉树  
  56. void buildBinTree(BinTree *root)  
  57. {  
  58.     char ch;  
  59.     scanf("%c", &ch);    //输入一个元素  
  60.     fpurge(stdin);  
  61.     if(ch == ' ')        //若输入的是空格符,表明二叉树为空,置*root为NULL  
  62.         *root = NULL;  
  63.     else {               //若输入的不是空格符,则将该值赋值给根节点的chValue, 递归建立左子树和右子树  
  64.         *root = (BinTree)malloc(sizeof(LNode));  
  65.         (*root)->chValue = ch;  
  66.         (*root)->leftMaxValue = 0;  
  67.         (*root)->rightMaxValue = 0;  
  68.   
  69.         buildBinTree(&(*root)->pleft);  
  70.         buildBinTree(&(*root)->pright);  
  71.     }  
  72. }  
  73.   
  74. //销毁二叉树,释放内存  
  75. void destroyBinTree(BinTree *root)  
  76. {  
  77.     if(*root != NULL) {  
  78.         destroyBinTree(&(*root)->pleft);  
  79.         destroyBinTree(&(*root)->pright);  
  80.   
  81.         free(*root);  
  82.         *root = NULL;  
  83.     }  
  84. }  
  85.   
  86. //前序遍历二叉树  
  87. void preOrderTraverse(BinTree root)  
  88. {  
  89.     if(root != NULL) {  
  90.         preOrderTraverse(root->pleft);  
  91.         printf("%c", root->chValue);  
  92.         preOrderTraverse(root->pright);  
  93.     }  
  94. }  
  95.   
  96. int main() {  
  97.     BinTree root;  
  98.     buildBinTree(&root);  
  99.     preOrderTraverse(root);  
  100.     printf("\n");  
  101.     int maxLen = 0;  
  102.     findMaxLen(root, &maxLen);  
  103.     printf("maxLen = %d\n", maxLen);  
  104.     destroyBinTree(&root);  
  105. }  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313315.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core 3.0】框架之十三 || 部署攻略

本文有配套视频&#xff1a;https://www.bilibili.com/video/av58096866/?p9一、部署1、WIN_独立部署感谢群里&#xff08;白云&#xff09;小伙伴&#xff0c;博主 小淋科技 提出的方案(需要 netcore2.1 )&#xff0c;我竟然忽略了&#xff0c;该打该打&#xff0c;官档都读…

Python import以及os模块

转自&#xff1a;http://jianpx.iteye.com/blog/486466 http://blog.chinaunix.net/uid-27838438-id-4087978.html Import: 1. import 实际上是python虚拟机把当前的globals()和locals()传进__builtins__.__import__内置函数了&#xff0c;所以实际上干活的是那个__import__函…

.Net Core3.0 配置Configuration

准备.NET core和.NET项目配置上有了很大的改变&#xff0c;支持的也更加丰富了比如命令行&#xff0c;环境变量&#xff0c;内存中.NET对象&#xff0c;设置文件等等。.NET项目我们常常把配置信息放到webConfig 或者appConfig中。配置相关的源码https://github.com/aspnet/Exte…

asp.net core 3.0 中使用 swagger

asp.net core 3.0 中使用 swaggerIntro上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用&#xff0c;那个项目的 api 比较简单&#xff0c;都是匿名接口不涉及到认证以及 api 版本控制&#xff0c;最近把另外一个 api 项目升级到了 3.0&#xff0c;还是遇到了一些…

由微软100题“求和不用for while”引出的static类成员的知识

转自&#xff1a;http://www.cnblogs.com/gysm/archive/2011/09/16/2179277.html C类中谈到static,我们可以在类中定义static成员&#xff0c;static成员函数&#xff01;Cprimer里面讲过&#xff1a;static成员它不像普通的数据成员&#xff0c;static数据成员独立于该类的任意…

MCN是啥?了解一下这5个互联网热词

骗子刷量&#xff0c;黑吃黑半斤八两前几天一件事火爆了互联网圈&#xff0c;一场搞笑的骗局&#xff0c;一场蜂群传媒导演的“僵尸舞台剧”&#xff1a;一条一夜爆红的视频 流量却为0&#xff01;。一个电商商家卖产品有投放需求&#xff0c;找到了微博上一家 MCN 机构的一个女…

为什么我不建议你去外包公司?

前言在我离开上家公司之前&#xff0c;我的直属领导找我聊了一番。除了问候我有没有找好下家之外&#xff0c;还千叮咛万嘱咐我千万不要去外包公司&#xff0c;否则会在简历上留下无法磨灭的污点。当时的我对于外包公司的了解并不深&#xff0c;只是道听途说外包公司很坑&#…

友浩达优选上新,原生态农产品,买得安心,吃得放心

大闸蟹还在热卖&#xff0c;需要的同学可以访问 各位一直支持队长的朋友们友浩达优选上新了本着为大家推荐好东西的想法商城里上架的商品都是队长亲自挑选有质量保证的口碑好商品这次&#xff0c;来看看队长又给大家带了哪些好东西本次上新全是各地优选原生态农产品食品优质、安…

树莓派4上跑 .NET Core 3.0,这次,真·64位!

导语前不久我写了一篇《Gentoo由于 Windows 10 IoT Core &#xff08;以及上面的UWP们&#xff09;暴尸荒野而苟且偷生使用 Linux 的我&#xff0c;已经彻底开荤了。最近我发现有个叫 Gentoo 的 Linux 系统&#xff0c;支持树莓派4的64位CPU。项目地址&#xff1a;https://gith…

asp.net core 使用 AccessControlHelper 控制访问权限

asp.net core 使用 AccessControlHelper 控制访问权限Intro由于项目需要&#xff0c;需要在基于 asp.net mvc 的 Web 项目框架中做权限的控制&#xff0c;于是才有了这个权限控制组件&#xff0c;最初只是支持 netframework&#xff0c;后来 dotnetcore 2.0 发布了之后添加了对…

Caffe 增加自定义 Layer 及其 ProtoBuffer 参数

转载自&#xff1a;http://blog.csdn.net/kkk584520/article/details/52721838 http://blog.csdn.net/kkk584520 博客内容基于新书《深度学习&#xff1a;21 天实战 Caffe》&#xff0c;书中课后习题答案欢迎读者留言讨论。以下进入正文。 在使用 Caffe 过程中经常会有这样的…

.NET Core 3.0愈加成熟,微软将不再把.NET Framework API移植给它

目前 .NET Core 3.0 拥有的 API 总数约为 .NET Framework API 的 80%&#xff0c;剩下尚未从 .NET Framework 移植到 .NET Core 的 API&#xff0c;微软考虑以开源的形式发布。微软方面表示&#xff0c;通过 .NET Core 3.0&#xff0c;他们现在已具备轻松移植现代 workload 所需…

参加 JSConf China 2019 是怎样的体验?VS Code 和 TypeScript 都很火

JSConf China 2019 于 10 月 19-20 日于上海尚浦中心举行。很高兴作为讲师参加这次的 JSConf。Day 1在 Day 1 给大家聊了聊 The Beauty of TypeScript。简单总结下我讲的 TypeScript 的 session。千言万语&#xff0c;汇聚成下面两页的 PPT。TypeScript 的使用场景&#xff08;…

Caffe阅读代码并修改

这个教程是最好理解的了 http://city.shaform.com/blog/2016/02/26/caffe.html 主要分成四個部份來講。首先是整個 Caffe 的大架構&#xff0c;以及一些重要的元件。 其次&#xff0c;我也研究了如何自己新增一個 layer。 接下來&#xff0c;再重新回到 Caffe 做更深入的解析…

ABP v1.0正式发布

经过长时间的开发终于发布了ABP v1.0&#xff01;感谢为该项目做出了贡献的你~https://github.com/abpframework/abp/releases

Ubuntu下用eclipse调试caffe code

本文地址&#xff1a;http://blog.csdn.net/mounty_fsc/article/details/51089864 1 运行范例脚本train_lenet.sh Ubuntu下终端行执行train_lenet.sh可训练lenet-5&#xff08;详细情况参考其他教程&#xff09;&#xff0c;能直观地看到lenet训练起来带情况。 train_lenet.sh…

idea使用jar包依赖,替换掉项目依赖

idea使用jar包依赖&#xff0c;替换掉项目依赖最近遇到了个问题&#xff0c;父子项目中&#xff0c;原本一个项目在idea下默认是项目依赖于另一个子项目&#xff0c;但是由于当前开发分支里不包含相应的代码&#xff0c;最新代码在别的分支&#xff0c;导致项目依赖时&#xff…

C#中Array.Sort()方法分析

Array.Sort()是在我们日常工作中非常常用的函数&#xff0c;不需要自己编写排序算法就可以方便的对数组进行排序。利用Array.Sort()排序具有以下特点&#xff1a;排序是不稳定的采用内省排序&#xff08;introspective sort&#xff09;这里简单解释一下内省排序。内省排序会先…

输入两个整数 n 和 m ,从数列 1 , 2 , 3.......n 中随意取几个数 ,使其和等于 m

转载自&#xff1a;http://blog.sina.com.cn/s/blog_7571423b01016707.html 编程求解&#xff1a;输入两个整数 n 和 m &#xff0c;从数列 1 &#xff0c; 2 &#xff0c; 3.......n 中随意取几个数 ,使其和等于 m , 要求将其中所有的可能组合列出来. 分析&#xff1a; 主要思…

张高兴的 .NET Core IoT 入门指南:(五)串口通信入门

在开始之前&#xff0c;首先要说明的是串口通信所用到的 SerialPort 类并不包含在 System.Device.Gpio NuGet 包中&#xff0c;而是在 System.IO.Ports NuGet 包中。之所以在这里介绍串口通信&#xff0c;是因为在嵌入式中串口通信是与其他设备进行交互的一种重要方式&#xff…