求二叉树的给定两个结点之间的距离

给定一颗二叉树,和两个给定的结点,求出这两个结点之间的距离

拿到题目时不要认为是求出二叉树的结点之间的最大距离,题目是求两个结点的之间的距离

题目有几种情况

  • 两个结点分布在根节点的左子树或者右子树
  • 一个结点分布在根节点的左子树,一个结点分布在根节点的右子树
  • 这两个结点是兄弟结点
  • 一个结点是另外结点的祖先结点

本题的解题思路是

利用层次遍历的方法,获取每个结点的高度,根节点左子树的高度用正数表示,根节点右子树的高度用负数表示

这样当两个结点分布在:一个结点分布在根节点的左子树,一个结点分布在根节点的右子树时,只需要两个结点的高度的差得绝对值即可

如果一个结点是另一个结点的祖先结点,只需要高度大的结点顺着祖先结点找到高度小得结点,如果到达相同的高度结点不相同说明是兄弟结点关系

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <algorithm>

using namespace std;

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int val_ = 0):val(val_),left(NULL),right(NULL){}
};

struct TreeHeightNode{
    int height;
    TreeNode* node;
    TreeHeightNode* parent;
    TreeHeightNode(TreeNode* node_ = NULL,int height_ = 0,TreeHeightNode* parent_ =NULL): node(node_), height(height_),parent(parent_){}
};

int getDistanceBetweenNode(TreeNode* root,TreeNode* a, TreeNode* b){
    if(root == NULL ) return -1;
    queue<TreeHeightNode *> que;
    que.push(new TreeHeightNode(root,0));
    bool flagA = false, flagB = false;
   // int heightA = 0, heightB = 0;
    TreeHeightNode* heightA =NULL, *heightB = NULL;
    while(!que.empty()){
        TreeHeightNode* tmp = que.front(); que.pop();
        TreeNode *node = tmp->node;
        if(node == a) {flagA = true;heightA = tmp;}
        if(node == b) {flagB = true;heightB = tmp;}
        if(flagA && flagB) break;
        if(node->left){
            if(node->val == 0) que.push(new TreeHeightNode(node->left,1,tmp));
            else if(node->val > 0) que.push(new TreeHeightNode(node->left,tmp->height+1,tmp));
            else if(node->val < 0) que.push(new TreeHeightNode(node->left,tmp->height-1,tmp));
        }
        if(node->right){
            if(node->val == 0) que.push(new TreeHeightNode(node->right,-1,tmp));
            else if(node->val > 0) que.push(new TreeHeightNode(node->right,tmp->height+1,tmp));
            else if(node->val < 0) que.push(new TreeHeightNode(node->right,tmp->height-1,tmp));
        }
    }

    if(!flagA || !flagB) return -1;
    else{
        int ha = heightA->height, hb =heightB->height;
       if(ha*hb <=0)  return ha-hb;
       else{
           if((ha >= hb && hb > 0) || (ha < hb && hb < 0)){
               int cnt = ha-hb;
               while(cnt-->0){
                   heightA=heightA->parent;
               }
               if(heightA == heightB) return ha-hb;
               else return ha-hb+2;
           }else{
               int cnt = hb - ha;
               while(cnt-- > 0){
                   heightB=heightB->parent;
               }
               if(heightB == heightA) return hb-ha;
               else return hb-ha+2;
           }
       }
    }
}

int main(){
    TreeNode *root = new TreeNode(1);
    TreeNode *left = new TreeNode(2);
    TreeNode *right = new TreeNode(3);
    root->left = left;
    root->right = right;
    TreeNode *left1 = new TreeNode(4);
    TreeNode *right1 = new TreeNode(5);
    left->left = left1;
    left->right = right1;
    TreeNode *left2 = new TreeNode(4);
    TreeNode *right2 = new TreeNode(5);
    left1->left = left2;
    left1->right = right2;
    cout<<getDistanceBetweenNode(root,left2,right)<<endl;
    return 0;
}

其实寻找两个结点的距离就是求两个结点的公共祖先结点,所以另一种方法是找到o最小其公共祖先结点

然后

求二叉树的给定两个结点之间的距离

时间: 2024-08-02 16:59:08

求二叉树的给定两个结点之间的距离的相关文章

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

求二叉树中任意两个结点的距离 实现步骤: 计算跟到第一个结点的距离: 计算跟到第二个结点的距离: 计算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)

019写程序在一棵二叉树中找到两个结点的最近共同祖先(keep it up)

写程序在一棵二叉树中找到两个结点的最近共同祖先. 分两种情况来讨论这个题: 第一种情况结点中没有指向父结点的指针 第二种情况接种有指向父节点的指针 我们先看第一种情况,结点中没有指向父结点的指针. 我们可以采用暴力搜索每一个结点,如果这个结点的子树中 有已知的两个结点,那我们就继续沿着左右子树找,如果左子树 能找到,我们就继续沿着左子树找,如果有子树能找到,我们就 沿着右子树找,不存在两个子树都能够找到. 代码: struct TreeNode {<pre name="code"

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

#pragma once #include <iostream> using namespace std; /****************  * 二叉树中 找两个结点的最近的公共祖先结点 ******************/ struct Node {     Node* left;     Node* right;     int value;     Node(int v)         :value(v)         ,left(NULL)         ,right(NU

求字符串中某两个字符之间的字符

这个简单,留作纪念,学习之初写的: 求两个A之间的字符,并打印出来: 1 #include<iostream> 2 using namespace std; 3 4 int main() 5 { 6 7 const char Stra[40] = "sdfjAI Love You So Much !Ajidhj";//呵呵,乱输的 8 const char *p; 9 p = Stra; 10 11 while (*p != '\0') 12 { 13 if (*p ==

计算两个经纬度之间的距离

//计算两个经纬度之间的距离 /** * 计算两点地理坐标之间的距离 * @param Decimal $longitude1 起点经度 * @param Decimal $latitude1 起点纬度 * @param Decimal $longitude2 终点经度 * @param Decimal $latitude2 终点纬度 * @param Int $unit 单位 1:米 2:公里 * @param Int $decimal 精度 保留小数位数 * @return Decimal

IOS 计算两个经纬度之间的距离

一 丶 -(double)distanceBetweenOrderBy:(double) lat1 :(double) lat2 :(double) lng1 :(double) lng2{ CLLocation *curLocation = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1]; CLLocation *otherLocation = [[CLLocation alloc] initWithLatitude:lat2

PHP MYSQL 搜索周边坐标,并计算两个点之间的距离

搜索附近地点,例如,坐标(39.91, 116.37)附近500米内的人,首先算出“给定坐标附近500米”这个范围的坐标范围. 虽然它是个圆,但我们可以先求出该圆的外接正方形,然后拿正方形的经纬度范围去搜索数据库.红色部分为要求的搜索范围,绿色部分为实际搜索范围. /** * 获取周围坐标 * Enter description here ... * @param unknown_type $lng 固定坐标经度 * @param unknown_type $lat 固定坐标纬度 * @para

计算两个经纬度之间的距离(python算法)

EARTH_REDIUS = 6378.137 def rad(d): return d * pi / 180.0 def getDistance(lat1, lng1, lat2, lng2): radLat1 = rad(lat1) radLat2 = rad(lat2) a = radLat1 - radLat2 b = rad(lng1) - rad(lng2) s = 2 * math.asin(math.sqrt(math.pow(sin(a/2), 2) + cos(radLat1

PHP计算两个坐标之间的距离

<?php /** * 计算两点之间的距离 * @param $lng1 经度1 * @param $lat1 纬度1 * @param $lng2 经度2 * @param $lat2 纬度2 * @param int $unit m,km * @param int $decimal 位数 * @return float */ function getDistance($lng1, $lat1, $lng2, $lat2, $unit = 2, $decimal = 2) { $EARTH_R