二叉树中两个结点的距离

问题

对于普通的二叉树,如何找到两个给定节点之间的距离?距离是指连接两个节点所需要的最小边的条数。

例如下面的二叉树:

这个问题很全面的考察了二叉树的相关的知识,建议大家先尝试自己解决

分析:

假设给定的节点为node1,node2,可以分为下面的两种情况:

1)node1是node2的祖先节点或孩子结点,可以理解为两个节点在一条线上。例如:Dist(2,4),Dist(6,1)

2)node1和node2没有直接或间接的父子关系。例如,Dist(4,3),他们需要一个共同的祖先结点1连接起来

假设lca是两个节点的最低公共祖先节点:

Dist(n1,n2)=Dist(root,n1)+Dist(root,n2)-2*Dist(root,lca)

这个公式已经涵盖了上面的两种情况。先找出lca,再求root节点到某个节点的距离就比较简单了。

参考代码:

 1 #include<list>
 2 #include<vector>
 3 #include<stdlib.h>
 4 #include<iostream>
 5 #include<algorithm>
 6
 7 using namespace std;
 8
 9 struct BinaryTreeNode//二叉树结点类型
10 {
11     char value;
12     BinaryTreeNode* left;
13     BinaryTreeNode* right;
14 };
15
16 void CreatBinaryTree(BinaryTreeNode** pRoot)//创建二叉树
17 {
18     char data;
19     cin>>data;
20     if(data!=‘.‘)
21     {
22         *pRoot=new BinaryTreeNode;
23         (*pRoot)->value=data;
24         CreatBinaryTree(&((*pRoot)->left));//创建左子树
25         CreatBinaryTree(&((*pRoot)->right));//创建右子树
26     }
27     else *pRoot=NULL;
28 }
29
30
31
32 bool GetNodePath(BinaryTreeNode* pRoot,char pNode,list<BinaryTreeNode*> &path)//获得结点路径
33 {
34     bool found=false;
35     path.push_back(pRoot);
36     if(pRoot->value==pNode) return true;
37     if(!found&&pRoot->left!=NULL)
38     {
39         found=GetNodePath(pRoot->left,pNode,path);
40     }
41     if(!found&&pRoot->right!=NULL)
42     {
43      found=GetNodePath(pRoot->right,pNode,path);
44     }
45     if(!found)
46     path.pop_back();
47     return found;
48 }
49 char GetLastCommonNode(list<BinaryTreeNode*> &path1,list<BinaryTreeNode*> &path2)//获得最近相同根结点的值
50 {
51     list<BinaryTreeNode*>::iterator ite1=path1.begin();
52     list<BinaryTreeNode*>::iterator ite2=path2.begin();
53     BinaryTreeNode* pLast;
54     while(ite1!=path1.end()&&ite2!=path2.end())
55     {
56         if(*ite1==*ite2)
57             pLast=*ite1;
58         ite1++;
59         ite2++;
60     }
61     return pLast->value;
62 }
63
64 void print(list<BinaryTreeNode*> &path)//打印路径
65 {
66     list<BinaryTreeNode*>::iterator ite;
67     for(ite=path.begin();ite!=path.end();++ite)
68     {cout<<(*ite)->value<<‘ ‘;}
69     cout<<endl;
70 }
71
72
73 void main()
74 {
75     BinaryTreeNode* pRoot;
76     CreatBinaryTree(&pRoot);
77     list<BinaryTreeNode*> path1,path2,path3;
78     cout<<"请输入结点字符:"<<endl;
79     char s1,s2;
80     cin>>s1>>s2;
81     GetNodePath( pRoot,s1,path1);
82     GetNodePath( pRoot,s2,path2);
83     char common=GetLastCommonNode(path1,path2);
84     GetNodePath( pRoot,common,path3);
85     print(path1);
86     print(path2);
87     print(path3);
88     int distance=path1.size()+path2.size()-2*path3.size();
89     cout<<s1<<" with "<<s2<<" distance is: "<<distance<<endl;
90 }

时间: 2024-08-08 12:39:58

二叉树中两个结点的距离的相关文章

二叉树中两个结点最近的公共祖先汇总

一.若二叉树为搜索二叉树 原题链接:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/#/description Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. According to the definition of LCA on

求解二叉树中两个结点的最低公共父结点

一,问题描述 构建一棵二叉树(不一定是二叉查找树),求出该二叉树中某两个结点的最低公共父结点.借用一张图如下: 结点8 和 结点5 的最低公共父结点为 结点2 二,二叉树的构建 与 求二叉树中第K层结点的个数 文章中的第二点:二叉树构建相同 三,求解最低公共父结点的算法实现 有两种思路,一种是通过中序遍历和后序遍历.由于中序遍历是先左子树中的结点,再访问根,再访问右子树中结点,因此这两个结点的公共父结点一定处于这两个结点之间. 如:中序遍历:8, 4, 9, 2, 5, 1, 6, 3, 7  

求二叉树中任意两个结点的距离

求二叉树中任意两个结点的距离 实现步骤: 计算跟到第一个结点的距离: 计算跟到第二个结点的距离: 计算lca: 计算跟到lca结点的距离: 结果为(1) + (2) - 2 * (4),因为重复计算了两次的从跟到lca结点的距离: 1 class Node(object): def __init__(self, value=0): self.value = value self.left = self.right = None def get_path_length(root, n, path)

求二叉树中两个节点的最远距离

问题定义 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数.写一个程序求一棵二叉树中相距最远的两个节点之间的距离. 计算一个二叉树的最大距离有两个情况: 情况A: 路径经过左子树的最深节点,通过根节点,再到右子树的最深节点. 情况B: 路径不穿过根节点,而是左子树或右子树的最大距离路径,取其大者. 思路: 1,后序遍历每一节点,找出该节点到最右边的距离以及最左边的距离: 2,找到之和最大的即可. //需保存左子树中最长距离.右子树最长

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

出题:求二叉树中距离最远的两个节点之间的距离,此处的距离定义为节点之间相隔的边数: 分析: 最远距离maxDis可能并不经过树的root节点,而树中的每一个节点都可能成为最远距离经过的子树的根节点:所以计算出以每个节点为根节点的子树的最 远距离,最后取他们的最大值就是整棵树的最远距离: 如果递归层次过多造成系统栈溢出,则可以使用stack堆栈结构存储递归节点,从而使用循环实现 解题: 1 struct Node { 2 int value; 3 Node *left; 4 Node *right

求解二叉树中两个节点的最近公共祖先(LCA)

/************************************************************************/ /* 非递归的方法 下面是一个简单的复杂度为 O(n) 的算法,解决LCA问题 1) 找到从根到n1的路径,并存储在一个向量或数组中. 2)找到从根到n2的路径,并存储在一个向量或数组中. 3) 遍历这两条路径,直到遇到一个不同的节点,则前面的那个即为最低公共祖先. */ /*************************************

二叉树中两个节点的最近公共父节点

这是京东周六的笔试题目   当时不在状态,现在想来肯定是笔试就被刷掉了,权当做个纪念吧.  这个问题可以分为三种情况来考虑: 情况一:root未知,但是每个节点都有parent指针此时可以分别从两个节点开始,沿着parent指针走向根节点,得到两个链表,然后求两个链表的第一个公共节点,这个方法很简单,不需要详细解释的. 情况二:节点只有左.右指针,没有parent指针,root已知思路:有两种情况,一是要找的这两个节点(a, b),在要遍历的节点(root)的两侧,那么这个节点就是这两个节点的最

编程之美 求二叉树中节点之间最大的距离

#include<iostream> using namespace std; //二叉树 节点结构 typedef struct TNODE_ { int data; struct TNODE_*left; struct TNODE_*right; }TNode; //获取树的高度=路径+1(最长路径经过的边数+1) int GetLRDistance(TNode*t) { int len=0; if(t==NULL) { return 0; }else{ int lenL=GetLRDis

求二叉树中两个节点的最低公共父节点

必须通过遍历查找一个节点的祖先集合,然后比较两个节点的祖先集合就可以找到最低的那个.这里采用后序遍历,并传入一个栈记录该节点的祖先节点.在每次访问一个节点时,先把这个节点压入栈,然后判断该节点是不是要查找的那个节点,如果是返回.接着查找它的左子树和右子树,当要查找的节点在它的左右子树中则返回.然后判断该节点与栈顶节点是否相同,是则弹出栈顶元素.这是因为相同就代表了在访问它的左右子树时没有添加新的节点,也就是说要查找的那个节点不在它的左右子树中,则该节点也就是不是要查找的节点的祖先. #inclu