二叉树寻找祖先C语言,在二叉树中找到两个节点的最近公共祖先(进阶)

#include

#include

#include

using namespace std;

struct TreeNode {

int val;

int left;

int right;

};

vector vec;

// 这种方法更练coding一些

unordered_map> maps;

void init_map(TreeNode* root){

if(root == NULL)

return;

unordered_map map_;

maps[root] = map_;

init_map(vec[root->left]);

init_map(vec[root->right]);

}

void head_record(TreeNode* node, TreeNode* head){

if(node == NULL)

return;

maps[node][head] = head;

head_record(vec[node->left], head);

head_record(vec[node->right], head);

}

void pre_right(TreeNode *l, TreeNode* r, TreeNode* root){

if(r == NULL)

return;

maps[l][r] = root;

pre_right(l, vec[r->left], root);

pre_right(l, vec[r->right], root);

}

void pre_left(TreeNode* l, TreeNode* r, TreeNode* root){

if(l == NULL)

return;

pre_right(l, r, root);

pre_left(vec[l->left], r, root);

pre_left(vec[l->right], r, root);

}

void sub_record(TreeNode* root){

if(root == NULL)

return;

pre_left(vec[root->left], vec[root->right], root);

// 原书貌似这里是个冗余操作,加上这两行会超时,去掉会过

// 加入相当于每个点加了个O(n^2)的操作,所以最后相当于O(n^3).

//sub_record(vec[root->left]);

//sub_record(vec[root->right]);

}

void set_map(TreeNode* root){

if(root == NULL)

return;

// 以root为公共祖先的点

head_record(vec[root->left], root);

head_record(vec[root->right], root);

sub_record(root);

set_map(vec[root->left]);

set_map(vec[root->right]);

}

int main(){

int n, root_val;

cin>>n>>root_val;

vec.resize(n+1);

vec[0] = NULL;

for(int i = 0;i

TreeNode* node = new TreeNode();

int fa, lch, rch;

cin>>fa>>lch>>rch;

node->left = lch;

node->right = rch;

node->val = fa;

vec[fa] = node;

}

// 初始化

init_map(vec[root_val]);

// 开始放点

set_map(vec[root_val]);

int m;

cin>>m;

for(int i = 0;i

{

int o1, o2;

cin>>o1>>o2;

//cout<

if(maps[vec[o1]].count(vec[o2])!=0)

cout<val<

if(maps[vec[o2]].count(vec[o1])!=0)

cout<val<

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值