您的位置:首页 > 其它

每日一题系列 - 二叉树节点求共同祖先

2009-10-12 23:00 337 查看
每天,自我肯定?还是自我否定?”

『每日一题』

题目取自清华大学《数据结构》题集,严蔚敏,米宁, 吴伟民

已知在二叉链表中,root为根节点, p^和q^为二叉树中两个节点,试编写求距离他们最近的共同祖先的算法。

============

题解:

如果此题的树结构是双向的,即子节点保留父节点的指针,父节点有指向子节点, 那么可以很快求解。现在考虑单向的情形。

用递归不可取,会大大增加算法复杂度。

将二叉链表实现为单向二叉树:

struct Tree

{

int value;

struct Tree * left;

struct Tree * right;

}

由于树的生长是单向向下的,子节点无法知道父亲节点,所以要分别通过遍历p^, q^得到其具体路径。

写了一个函数,能够实现二叉树的遍历,同时能够将到达目标节点所进过的路径压入栈,并将栈作为返回值

#include "stdafx.h"
#include <iostream>
using namespace std;
#include   <stack>
struct Tree
{
int value;
struct Tree * left;
struct Tree * right;
}
stack<Tree *> bianli(Tree * root, Tree * target)
{
stack<Tree *> s;
stack<Tree *> path;
Tree * node=root;
//先根遍历
while(true)
{
cout<<"current node: "<<node->value<<endl;
path.push(node);
if(target==node){
cout<<"find the node"<<endl;
return path;
}
if(NULL!=node->left)
{
if(NULL!=node->right)
{
s.push(node->right);
}
node=node->left;
}
else if(NULL!=node->right)
{
node=node->right;
}
else if(!s.empty())
{
while(path.top()->right!=s.top())
path.pop();
node=s.top();
s.pop();
}
else
{
break;
}
}
return path;
}


通过这个函数,得到栈以后(根节点在栈底,目标节点在栈头),

stack_p=bianli(root,p);

stack_q=bianli(root,q);

再通过一次出栈、入栈操作,将其反序,得到:

stack_p.reverse()

stack_q.reverse()

然后再用:

Tree * coFather;
while(stack_p.top()==stack_q.top())
{
coFather=stack_p.top();
stack_p.pop();
stack_q.pop();
}
//出循环以后, coFather就是答案
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: