博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
变形二叉树中节点的最大距离(树的最长路径)——非递归解法
阅读量:4677 次
发布时间:2019-06-09

本文共 3643 字,大约阅读时间需要 12 分钟。

问题描写叙述:

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

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

                                  n1

                             /             \

                          n2             n3

                       /        \

                   n4          n5

                 /     \         /   \

              n6    n7    n8    n9

             /                       /

         n10                 n11

不幸的是。我一開始就把题目看错了:把“父子节点之间的连线看成是双向的”理解成为,在节点的定义中真的有指向父节点的指针。。。。

将错就错。我干脆把错误理解的题目先做出来再说。于是。为了实现非递归解法。自己定义了一种奇怪的数节点struct。。

于是。事情变成了:我为了解决题目。改了题目要求。。。。

。。

事实上对于原题。依据树结构,用我所定义的节点,初始化一棵变形二叉树,再用这样的非递归解法求解就可以。仅仅只是初始化树还须要做些工作。

这样的解法也不是全然没有意义。

。。

对于原题的解法。以后再说。

算法:

题目就是求一棵树中的最长路径

对于节点t,以它为根的树的最长路径longstpath一定是下列三个数中的最大值

①t的左子树的longstpath

②t的右子树的longstpath

③t的左子树的深度+t的右子树的深度+2

                                                                               ——结论1

所以对于每一个节点。有两个重要的属性:①以该节点为根的树的深度②以该节点为根的树的最大路径长度

从每一个叶节点開始,自底向上进行处理。

每次处理的过称为:

若该节点两个属性均已确定,将它们“告知”父节点。父节点得到全部子节点的属性后,依据结论1方可确定自己的两个属性。继续向上“报告”自己的属性。

对于没有了解到全部子节点属性的父节点,让他在每一次处理中”等待“子节点的报告,显然。须要一个队列queue存储正在等待的节点。

代码实现:

#include
#include "Queue.h"using namespace std;//节点结构体struct BinaryTreeNode{ BinaryTreeNode* father = NULL;//指向父节点 BinaryTreeNode* left = NULL; BinaryTreeNode* right = NULL; int arrived = 0;//记录子树深度值到达的数目。取值为0或1或2 int depth = 0;//以此节点为根的树的深度 int longstpath = 0;//以此节点为根的树中的最长路径 bool stored = false;//是否已入列等待};//取大值int max2(int a, int b){ if (a > b) return a; else return b;}//取大值int max3(int a, int b, int c){ return max2(max2(a, b), c);}//依据不同情况(有的节点无左/右子节点),更新longstpath//longstpath一定是下面三数中的最大值:左子树的longstpath。右子树的longstpath。左右子树深度和+2void SetLongstpath(BinaryTreeNode* temp){ int lpath, rpath, ldepth, rdepth; if (temp->left) { lpath = temp->left->longstpath; ldepth = temp->left->depth; } else lpath = ldepth = 0; if (temp->right) { rpath = temp->right->longstpath; rdepth = temp->right->depth; } else rpath = rdepth = 0; temp->longstpath = max3(lpath, rpath, ldepth + rdepth + 2);//更新最长路径longstpath}int FindPath(Queue
&queue){ BinaryTreeNode* temp; while (!queue.IsEmpty()) { queue.Delete(temp); temp->stored = false; if (temp->arrived == 2)//子节点都到达了,万事俱备 { SetLongstpath(temp);//更新temp的Longstpath if (temp->father)//若不是根节点。,则上移该节点(即对父节点进行处理) { temp->father->depth = max2(temp->father->depth, temp->depth + 1);//更新父节点的深度值 temp->father->arrived++;//到达子节点数目+1 if (!temp->father->stored)//说明这是第一个到达的子节点。该父节点从未入列,则将其入列 { queue.Add(temp->father); temp->father->stored = true; } } else//根节点,返回longstpath return temp->longstpath; } if (temp->arrived == 1)//有子节点还没到,更新longstpath的条件不充分。又一次入列等待子节点 { queue.Add(temp); temp->stored = true; } }}void main(){ BinaryTreeNode* n1 = new BinaryTreeNode; BinaryTreeNode* n2 = new BinaryTreeNode; BinaryTreeNode* n3 = new BinaryTreeNode; BinaryTreeNode* n4 = new BinaryTreeNode; BinaryTreeNode* n5 = new BinaryTreeNode; BinaryTreeNode* n6 = new BinaryTreeNode; BinaryTreeNode* n7 = new BinaryTreeNode; BinaryTreeNode* n8 = new BinaryTreeNode; BinaryTreeNode* n9 = new BinaryTreeNode; BinaryTreeNode* n10 = new BinaryTreeNode; BinaryTreeNode* n11 = new BinaryTreeNode; //构造二叉树 n2->father = n3->father = n1; n4->father = n5->father = n2; n6->father = n7->father = n4; n8->father = n9->father = n5; n10->father = n6; n11->father = n9; n6->left = n10; n4->left = n6; n4->right = n7; n9->left = n11; n5->left = n8; n5->right = n9; n2->left = n4; n2->right = n5; n1->left = n2; n1->right = n3; n3->arrived = 2;//叶节点初始为2 n7->arrived = 2; n8->arrived = 2; n10->arrived = 2; n11->arrived = 2; n6->arrived = 1;//但孩子节点初始为1 n9->arrived = 1; Queue
queue; queue.Add(n3); n3->stored = true; queue.Add(n7); n7->stored = true; queue.Add(n8); n8->stored = true; queue.Add(n10); n10->stored = true; queue.Add(n11); n11->stored = true; cout << "最大路径长度:" << FindPath(queue) << endl; system("pause");}

转载于:https://www.cnblogs.com/blfshiye/p/5387463.html

你可能感兴趣的文章
多张照片拍摄、图片浏览
查看>>
html(5) css
查看>>
Azure Web连接到Azure MySql Db
查看>>
《麻辣江湖》即将上线!
查看>>
Mybatis中mapper.xml文件判断语句中的单双引号问题
查看>>
frameset和frame
查看>>
饥饿的小易(规律,同余大数)
查看>>
ats透明代理
查看>>
PHP 小代码
查看>>
2016/03/16 codes
查看>>
2018年7月21日工作总结
查看>>
Linux shell 命令判断执行语法 ; , && , ||
查看>>
vim代码格式化插件clang-format
查看>>
What does the dot after dollar sign mean in jQuery when declaring variables?
查看>>
windows registry
查看>>
jquery 动画总结(主要指效果函数)
查看>>
【BZOJ4155】[Ipsc2015]Humble Captains
查看>>
【事件】阻止事件的冒泡
查看>>
mac os 安装 geckodriver
查看>>
【数据分析 R语言实战】学习笔记 第十一章 对应分析
查看>>