二叉树中找两个结点的最近的公共祖先结点
2016-06-09 12:04
393 查看
#pragma once #include <iostream> using namespace std; /**************** * 二叉树中 找两个结点的最近的公共祖先结点 ******************/ struct Node { Node* left; Node* right; int value; Node(int v) :value(v) ,left(NULL) ,right(NULL) {} };// 方法一 int count 计数
int _find_ancestor(Node* root, Node* & ancestor, const Node* a, const Node* b) { if (root == NULL) { return 0; } int count = 0; count += _find_ancestor(root->left, ancestor, a , b); if (root == a || root == b) { count += 1; } /*if (count == 2) { ancestor = root; }*/ count += _find_ancestor(root->right, ancestor, a, b); if (count == 2) { ancestor = root ; count = 0; // 防止返回 时 上面count的值还是2 导致 ancestor不准确 被覆盖 } return count; } void test_find_ancestor() { // 1 // 2 3 // 4 5 Node n1(1); Node n2(2); Node n3(3); Node n4(4); Node n5(5); n1.left = &n2; n1.right = &n3; n2.left = &n4; n2.right = &n5; Node* ancestor = NULL; // 4 5 // _find_ancestor(&n1, ancestor,&n4, &n5); // 2 5 // _find_ancestor(&n1, ancestor,&n2, &n5); // 5 3 _find_ancestor(&n1, ancestor,&n5, &n3); }// 方法二 bool判别
bool find_ancestor_bool(Node* root, Node* & ancestor, const Node* a, const Node* b) { if (root == NULL) { return false; } bool b_left = find_ancestor_bool(root->left, ancestor, a, b); bool b_right = find_ancestor_bool(root->right, ancestor, a, b); if (root == a || root == b) { if (b_left || b_right) { ancestor = root; } return true; } if (b_left && b_right) { ancestor = root; } return b_left || b_right; } void test_find_ancestor_bool() { // 1 // 2 3 // 4 5 Node n1(1); Node n2(2); Node n3(3); Node n4(4); Node n5(5); n1.left = &n2; n1.right = &n3; n2.left = &n4; n2.right = &n5; Node* ancestor = NULL; // 4 5 //find_ancestor_bool(&n1, ancestor,&n4, &n5); // 2 5 // find_ancestor_bool(&n1, ancestor,&n2, &n5); // 5 3 // find_ancestor_bool(&n1, ancestor,&n5, &n3); // 1 5 find_ancestor_bool(&n1, ancestor,&n1, &n5); }
// 方法3 利用栈 数组或 链表 记录 找到结点的 路径 最后 遍历两个 栈(数组或链表) 找到第一次出现比相同的点的前一个 即为公共祖先
// 注意 如果当前不是 返回时 要将当前压栈的 元素弹出 栈用引用传入
// 这里以 vector 为例 方便遍历
#include<vector> void find_ancestor_vector_R(Node* root, vector<Node*>& va,vector<Node*>& vb, Node* a, Node* b, Node* &ancestor) { if (root == NULL) { return; } va.push_back(root); vb.push_back(root); find_ancestor_vector_R(root->left, va, vb, a, b, ancestor); find_ancestor_vector_R(root->right, va, vb, a, b, ancestor); if (va.back() != a) { va.pop_back(); } if (vb.back() != b) { vb.pop_back(); } } Node* find_ancestor_vector(Node* root, Node* a, Node* b) { vector<Node*> va,vb; Node* ancestor = NULL; find_ancestor_vector_R(root, va, vb, a, b, ancestor); // 找va vb 的分叉点 之前的点 int i = 0; while (i < va.size() && i < vb.size() && va[i] == vb[i]) { ancestor = va[i]; i++; } return ancestor; } void test_find_ancestor_vector() { // 1 // 2 3 // 4 5 Node n1(1); Node n2(2); Node n3(3); Node n4(4); Node n5(5); n1.left = &n2; n1.right = &n3; n2.left = &n4; n2.right = &n5; Node* ancestor = NULL; // 4 5 ancestor = find_ancestor_vector(&n1, &n4, &n5); // 2 5 ancestor = find_ancestor_vector(&n1, &n2, &n5); // 5 3 ancestor = find_ancestor_vector(&n1, &n5, &n3); // 1 5 ancestor = find_ancestor_vector(&n1, &n1, &n5); }
本文出自 “城市猎人” 博客,请务必保留此出处http://alick.blog.51cto.com/10786574/1787620
相关文章推荐
- NetOS 及 NetOS 企业版/教育版正式发布
- javascript常用互动方法
- foreach的原理
- L3-007. 天梯地图
- 使用hadoop mapreduce分析mongodb数据:(1)
- Python 各种测试框架简介(一):doctest
- mysql下优化表和修复表命令使用说明(REPAIR TABLE和OPTIMIZE TABLE)
- matlab 可视化 —— axis
- 一个32岁入门的70后程序员给我的启示
- iOS应用发布篇一(开发者账号申请)
- 函数popen()
- 服务器nginx+nodejs配置
- java集合整理
- [从头读历史] 第247节 夏商与西周时期的全面解读
- 详解Linux中将应用程序打包为Snap软件包格式的方法
- Android 退出程序 关闭所有Activity 的方法
- Python学习笔记 —— 字典
- 文章标题
- C#使用WinRar命令进行压缩和解压缩操作的实现方法
- 爸第一次来大学