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
  • 相关阅读:
    Ext JS学习第三天 我们所熟悉的javascript(二)
    Ext JS学习第二天 我们所熟悉的javascript(一)
    Ext JS学习第十七天 事件机制event(二)
    Ext JS学习第十六天 事件机制event(一)
    Ext JS学习第十五天 Ext基础之 Ext.DomQuery
    Ext JS学习第十四天 Ext基础之 Ext.DomHelper
    Ext JS学习第十三天 Ext基础之 Ext.Element
    Ext JS学习第十天 Ext基础之 扩展原生的javascript对象(二)
    针对错误 “服务器提交了协议冲突. Section=ResponseHeader Detail=CR 后面必须是 LF” 的原因分析
    C# 使用HttpWebRequest通过PHP接口 上传文件
  • 原文地址:https://www.cnblogs.com/shijianchuzhenzhi/p/12431454.html
Copyright © 2011-2022 走看看