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 }

  • 相关阅读:
    如何提取Redis中的大KEY
    VIM标记 mark 详解
    JAVA编写的一个简单的Socket实现的HTTP响应服务器
    onenote 直接发布文章到CSDN
    guava学习笔记--字符串处理
    带打印子结点的自底向上算法
    动态规划算法3
    动态规划算法2
    一个菜鸟学习动态规划算法的过程
    php取得当前时间函数
  • 原文地址:https://www.cnblogs.com/wxdjss/p/5698071.html
Copyright © 2011-2022 走看看