二叉树-最低公共父节点(1)

给定一个二叉树(不是二叉查找树),和两个节点,求这两个节点的最低公共父节点。
我们先介绍一个暴力的思路:
遍历并判断。首先我们写一个判断一个父节点是否含有一个子节点的函数hasnode(node* father,node* pnode) 然后我们从上到下遍历每一条路径;
有这么几种情况:

  • 两节点在最低公共父节点的左子树
  • 两节点在最低公共父节点的右子树
  • 两节点在最低公共父节点的左边和右边各一个

头结点不需要判断,从头结点的left和right分别开始;

  • 如果发现头结点的 左子树/右子树 两个节点都有,那么
    1,这个节点就是最低公共父节点,对应的情况是这个父节点等于其中的一个节点,那么就不需要往下找了
    2,否则递归调用这个函数,把当前节点设为头结点,递归查找
  • 如果发现一个节点的左右两个分支分别含有两个节点,那么返回当前的头结点(注:我们这里使用递归调用,这个判断语句写在最后面的话,就不会把整个树的头结点当成符合条件的节点)

代码如下:

//find the last common parent node of two nodes
struct node
{
    int data;
    struct node* lnode;
    struct node* rnode;
};

//way1: check every path

bool hasnode(node* ptree, node* pnode)
{
    if (!ptree | !pnode)
        return;
    if (ptree == pnode)
        return true;
    else if (ptree->lnode)
        return hasnode(ptree->lnode, pnode);
    else if (ptree->rnode)
        return hasnode(ptree->rnode, pnode);
    else return false;
}
node* findLastCommonNode(node* ptree, node* node1, node* node2)
{
    if (!ptree || !node1 || !node2)
    {
        return 0;
    }
    bool leftHasNode1=0;
    bool leftHasNode2=0;

    if (ptree->lnode)
    {
        leftHasNode1 = hasnode(ptree->lnode, node1);
        leftHasNode2 = hasnode(ptree->lnode, node2);
    }
    if (leftHasNode1&&leftHasNode2)
    {
        if (ptree->lnode == node1 || ptree->rnode == node2)
            return ptree;
        else return findLastCommonNode(ptree->lnode, node1, node2);
        //像这种要一层一层的向下判断的,用递归可以减小代码的复杂度!
    }

    //check right
    bool rightHasNode1 = 0;
    bool rightHasNode2 = 0;
    if (ptree->rnode)
    {
        if (!leftHasNode1)//search only if left doesnot has node
        rightHasNode1 = hasnode(ptree->lnode, node1);
        if (!leftHasNode2)
        rightHasNode2 = hasnode(ptree->rnode, node2);
    }
    if (rightHasNode1&&rightHasNode2)
    {
        if (ptree->lnode == node1 || ptree->rnode == node2)
            return ptree;
        else return findLastCommonNode(ptree->rnode, node1, node2);
    }

    if (leftHasNode1&&rightHasNode2 || leftHasNode2&&rightHasNode1)
        return ptree;
}

这种思路由于要遍历整个树,因此复杂度为O(N2),有没有更好的方法呢?看下一篇文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • B树的定义 一棵m阶的B树满足下列条件: 树中每个结点至多有m个孩子。 除根结点和叶子结点外,其它每个结点至少有m...
    文档随手记阅读 13,470评论 0 25
  • 树的概述 树是一种非常常用的数据结构,树与前面介绍的线性表,栈,队列等线性结构不同,树是一种非线性结构 1.树的定...
    Jack921阅读 4,526评论 1 31
  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 1,636评论 0 7
  • 什么是二叉树? 引用自百度百科:在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(...
    AnICoo1阅读 1,404评论 0 1
  • 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比,二叉树有如下特点: 每个结点最多只有两棵子...
    sunhaiyu阅读 6,581评论 0 14