zoukankan      html  css  js  c++  java
  • 求二叉树两结点的最近公共祖先结点

    任务描述

    给定一个二叉树, 找到该树中两个指定结点的最近公共祖先结点

    相关知识

    为了完成本关任务,你需要掌握: 1、二叉树两结点最近公共祖先的定义 2、递归方法查找最近公共祖先的算法

    1、二叉树两结点最近公共祖先的定义 二叉树中有两个结点 p、q,则p,q的所有公共祖先中,层次最大的公共祖先结点即为最近公共祖先结点。例,如下图(1)所示 ,

    2、递归方法查找最近公共祖先的算法 在以root为根节点的二叉树中,查找p和q两结点的最近公共结点,即在root为根节点的二叉树中查找p和q两个结点。 1、若根结点root为NULL,则查找失败,最近公共祖先结点为NULL 2、若根结点root为p或q,查找成功,则最近公共祖先结点即为根结点root; , 3、若根结点root不为p或q,则分别在root的左右两棵子树中查找p和q; 3.1)若p和q在根结点的异侧(即在左右子树中,一棵子树中存在p,另一棵子树中存在q),则root即为p和q的最近公共祖先结点; , 3.2)若p和q在根结点的同侧(即在左子树和右子树中,一棵子树中同时存在p和q,且最近公共祖先结为k,在另一棵子树中不存在p和q,查找失败),则p和q的最近祖先结点为k; ,

    编程要求

    在右侧编辑器中补充代码,完成CreateBiTree和lowestCommonAncestor两个操作函数,以实现二叉树的创建和求指定的两个结点的最近公共结点。具体要求如下:

    • CreateBiTree:利用先序遍历创建二叉树,返回其根指针。
    • lowestCommonAncestor:求指定的两个结点的最近公共结点。

    注意:在实现两个函数的函数体内可调用其他操作。

    输入输出说明

    输入为一组测试用例,一组输入用例为两行,第一行为二叉树的扩展先序遍历,其中‘#’字符表示空孩子结点,第二行为指定需要查找最近公共祖先结点的两结点,输出为所求最近公共祖先结点。

    输入: AB##CD### BD

    输出: A (解析输入的扩展先序遍历序列表示的二叉树如下所示) ,

    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    #include <iostream>
    #include <string>
    using namespace std;
    struct BNode{//二叉树节点
        BNode(const char d='#'):data(d), left(nullptr), right(nullptr) {};
        char data;
        BNode* left;
        BNode* right;
    };
    //根据先序遍历构建一棵二叉树,返回root指针
    BNode* constructBinaryTree(const string& preOrder, unsigned& index){
        if (preOrder.size() == 0 || index == preOrder.size() || preOrder[index] == '#')//若空串或者index超出范围,则返回空指针
            return nullptr;
        BNode* T = new BNode(preOrder[index++]);
        T->left = constructBinaryTree(preOrder, index);
        T->right = constructBinaryTree(preOrder, ++index);
        return T;
    }
    typedef char ElemType; //二叉链表中结点元素类型
    typedef struct BiTNode
    {
        ElemType data;
        struct BiTNode* left, * right;
    }BiTNode, * BiTree; //二叉链表的类型定义
    
    BiTree CreateBiTree();// 利用先序遍历创建二叉树,返回根指针。
    
    BNode* LowestCommonAncestor (BNode* Root,char p,char q){ 
                                                                            
        if(!Root)
            return NULL;
    
        if(Root->data==p||Root->data==q) //若子身结点是p,或者q。返回自身结点
            return Root;
    
        BNode* left=LowestCommonAncestor (Root->left,p,q); //在树的左进行查找
        BNode* right=LowestCommonAncestor (Root->right,p,q); //在树的右进行查找
    
        if(left!=NULL&&right!=NULL)
            return Root;            
        if(left==NULL&&right==NULL)    
            return NULL;
        return left==NULL? right:left;                                 
    } 
    
    
    int main()
    {
        string str;
        while (cin >> str){
            unsigned index = 0;
            BNode* root = constructBinaryTree(str, index);
            
            ElemType p, q;
            getchar();
            p = getchar();
            q = getchar(); 
            BNode* Ancestor;
            Ancestor = LowestCommonAncestor(root, p, q);
            printf("%c", Ancestor->data); 
            cout << endl;
        }
    }
  • 相关阅读:
    刚开发的游戏《天黑请闭眼》
    用手机控制服务器
    专业网站打包/解包asp工具(E文精装版本)!
    令我爱慕的女子(转自7di.net)
    8088 汇编速查手册
    Asp调用函数是否会影响性能?
    文档管理器
    ubuntu install xxx.deb
    Java线程池的原理及几类线程池的介绍
    ubuntu download file path
  • 原文地址:https://www.cnblogs.com/xxxsans/p/14004541.html
Copyright © 2011-2022 走看看