zoukankan      html  css  js  c++  java
  • 二叉树中两个结点的距离

    问题
    对于普通的二叉树,如何找到两个给定节点之间的距离?距离是指连接两个节点所需要的最小边的条数。
    例如下面的二叉树:
    这个问题很全面的考察了二叉树的相关的知识,建议大家先尝试自己解决
    分析:
    假设给定的节点为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 }

  • 相关阅读:
    再次或多次格式化导致namenode的ClusterID和datanode的ClusterID之间不一致的问题解决办法
    Linux安装aria2
    POJ 3335 Rotating Scoreboard 半平面交
    hdu 1540 Tunnel Warfare 线段树 区间合并
    hdu 3397 Sequence operation 线段树 区间更新 区间合并
    hud 3308 LCIS 线段树 区间合并
    POJ 3667 Hotel 线段树 区间合并
    POJ 2528 Mayor's posters 贴海报 线段树 区间更新
    POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
    POJ 3468 A Simple Problem with Integers 线段树成段更新
  • 原文地址:https://www.cnblogs.com/wxdjss/p/5698071.html
Copyright © 2011-2022 走看看