zoukankan      html  css  js  c++  java
  • 求二叉树的最近公共节点

    typedef struct Node{                        
        struct Node *lchild;                    
        char data;                
        struct Node *rchild;
    }BTNode;  
    //求二叉搜索树的公共祖先
    1.二叉搜索树具有一个很好的特点。以当前结点为根节点的左边结点的值都是小于根节点的值,右边结点的值都大于根节点的值。 
    2.根据这个特点,如果给的两个节点的值都小于根节点,那么它们的最低公共祖先就一定在它左子树。 
    3.如果给的两个节点的值都大于根节点,那么它们的最低公共祖先就一定在它右子树。 
    4.如果一个结点的值大于根节点的值,一个结点的值小于根节点的值,那么这个根节点就是它的最低公共祖先。
    BTNode* getLowestCommonParent(BTNode* root, BTNode* node1, BTNode* node2)
    {
        if (root == NULL || node1 == NULL || node2 == NULL)
            return NULL;
    
        if ((node1->data < root->data) && (node2->data< root->data))
        {
            return getLowestCommenParent(root->lchild, node1, node2);
        }else if ((node1->data > root->data) && (node2->data > root->data)){
            return getLowestCommenParent_R(root->rchild, node1, node2);
        }else{
            return root;
        }        
    }
    //求普通二叉树的最低公共祖先
    二叉树问题一般都可以用递归去解决,要想通过递归实现,就需要先确定临界条件。那么什么是临界条件呢?换句话说,临界条件就是递归中能够直接返回的特殊情况。
    (1)第一点则是最常见的“判空”,判断根结点是否是空节点,如果是,那么肯定就可以马上返回了;
    (2)再来考虑题意,在以root为根结点的树中找到p结点和q结点的最近公共祖先,那么特殊情况是什么呢?很显然,特殊情况就是根结点就等于q结点或p结点的情况,想一下,如果根结点为二者之一,那么根结点就必定是最近公共祖先了,这时直接返回root即可。
    由此看来,这道题共有三种特殊情况即root == q 、root == p以及root==null,均直接返回root即可。
    根据临界条件,此题已经被简化为查找以root为根结点的树上是否有p结点或者q结点,如果有就返回p结点或q结点,否则返回null。
    这样一来就很简单了,从左右子树分别进行递归,即查找左右子树上是否有p结点或者q结点,就一共有4种情况:
    第一种:左右子树均没有找到p或者q结点;(虽然题上说p和q结点必定都存在,但递归的时候必须考虑所有情况,因为题目是针对整棵树,而递归会到局部,局部不一定都满足整体条件)
    第二种:左子树上能找到,但右子树上找不到,此时就应当直接返回左子树的查找结果;
    第三种:右子树上能找到,但左子树上找不到,此时就应当直接返回右子树的查找结果;
    第四种:左右子树上均能找到,说明此时的p和q结点分居root两侧,此时就应当直接返回root结点了。
    
    BTNode* getLowestCommonParent(BTNode* root, BTNode* node1, BTNode* node2)
    {
        if (root == NULL || node1 == root || node2 == root)
            return root;
        BTNode* left =getLowestCommonParent(root->lchild, node1,node2);
        BTNode* right =  getLowestCommonParent(root->rchild, node1,node2);
    
        if(left==NULL && right==NULL){
              return NULL;
        } else if(left!=NULL && right==NULL){
              return left;
        } else if(right!=NULL&&left==NULL){
              return right;
        } else{
              return root;
        }        
    }
    二叉树任意两节点之间的最短路径长度
    1.求出两个节点的最近公共祖先lowestCommonRoot
    2.利用深度搜索(先序)分别求出node1和node2到root的路径
    3.对两个路径长度求和即得所求
    
    bool getPath(BTNode* root,BTNode* target,Queue<TreeNode*> queue){
        if (root==target){
            return true;
        }     
        in(queue,root);
        bool found=false;
        if (root->lchild!=NULL)
            found=getPath(root->lchild,target,queue);
        if (!found && root->rchild!=NULL)
            found=getPath(root->rchild,target,queue);
        if (!found)
            reverseOut(queue);
        return found; 
    }
    
    
    BTNode* lowestCommonRoot = getLowestCommonParent(root,node1,node2);
    getPath(lowestCommonRoot,node1,queue1);
    getPath(lowestCommonRoot,node2,queue2);
    queue1->length+queue2->length
  • 相关阅读:
    【浅谈数位计数一类问题】
    2.2、idea 中写spark sql
    javascript事件之鼠标滚轮(mousewheel)和DOMMouseScroll事件
    JS 判断鼠标滚轮的上下滚动
    gulp 用法 小结
    'gulp'不是内部或者外部命令,也不是可运行的程序
    Gulp的安装与配置
    前端构建工具gulpjs的使用介绍及技巧
    【转】弧度和角度的转换
    前端构建工具gulpjs的使用介绍及技巧
  • 原文地址:https://www.cnblogs.com/shijianchuzhenzhi/p/12431454.html
Copyright © 2011-2022 走看看