任务描述

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

相关知识

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

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

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

编程要求

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

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

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

输入输出说明

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

输入: AB##CD### BD

输出: A (解析输入的扩展先序遍历序列表示的二叉树如下所示) 求二叉树两结点的最近公共祖先结点_最近公共祖先_05

 

#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;
    }
}