求二叉树两结点的最近公共祖先结点
任务描述
给定一个二叉树, 找到该树中两个指定结点的最近公共祖先结点
相关知识
为了完成本关任务,你需要掌握: 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; } }