Geeks 一般二叉树的LCA
不是BST,那么搜索两节点的LCA就复杂点了,由于节点是无序的。
以下是两种方法,都写进一个类里面了。
当然须要反复搜索的时候。能够使用多种方法加速搜索。
#include <iostream>
#include <vector>
using namespace std; class LCANormalTree
{
struct Node
{
int key;
Node *left, *right;
Node(int k) : key(k) , left(NULL), right(NULL) {}
}; //method 1:
bool findPath(Node *root, vector<Node *> &path, int k)
{
if (!root) return false;
path.push_back(root);
if (root->key == k) return true;
if (findPath(root->left, path, k) || findPath(root->right, path, k))
return true; path.pop_back();
return false;
} Node *findLCA(Node *root, int n1, int n2)
{
vector<Node *> pathN1, pathN2;
if (!findPath(root, pathN1, n1) || !findPath(root, pathN2, n2))
return NULL; int i = 0;
for (; i < (int) pathN1.size() && pathN1[i] == pathN2[i]; i++);
return pathN1[i-1];
} //Method 2:
Node *findLCAUtil(Node *root, int n1, int n2, bool &v1, bool &v2)
{
if (!root) return NULL;
if (root->key == n1)
{
v1 = true;
return root;
}
if (root->key == n2)
{
v2 = true;
return root;
}
Node *left = findLCAUtil(root->left, n1, n2, v1, v2);
Node *right = findLCAUtil(root->right, n1, n2, v1, v2); if (left && right) return root;
return left? left:right;
} bool find(Node *root, int k)
{
if (!root) return false;
if (root->key == k || find(root->left, k) || find(root->right, k))
return true;
return false;
} Node *findLCA_2(Node *root, int n1, int n2)
{
bool v1 = false, v2 = false;
Node *lca = findLCAUtil(root, n1, n2, v1, v2);
//当两者在不同一边的时候v1&&v1,当一个为另外一个的单亲节点的时候,那么就出现后面两种情况了。
if (v1 && v2 || v1 && find(lca, n2) || v2 && find(lca, n1))
return lca;
return NULL;
} Node *root;
public:
LCANormalTree()
{
cout<<"Algorithm 1 run\n";
run_1();
cout<<"\nAlgorithm 2 run\n";
run_2();
} void run_1()
{
root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node *t = findLCA(root, 4, 5);
cout << "LCA(4, 5) = " << (t? t->key : -1);
t = findLCA(root, 4, 6);
cout << "\nLCA(4, 6) = " << (t? t->key : -1);
t = findLCA(root, 3, 4);
cout << "\nLCA(3, 4) = " << (t? t->key : -1);
t = findLCA(root, 2, 4);
cout << "\nLCA(2, 4) = " << (t? t->key : -1);
cout << endl; deleteTree(root);
} void run_2()
{
root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node *lca = findLCA(root, 4, 5);
if (lca != NULL)
cout << "LCA(4, 5) = " << lca->key;
else
cout << "Keys are not present "; lca = findLCA(root, 4, 10);
if (lca != NULL)
cout << "\nLCA(4, 10) = " << lca->key;
else
cout << "\nKeys are not present "; cout<<endl;
deleteTree(root);
} ~LCANormalTree()
{
if (root) deleteTree(root);
} void deleteTree(Node *&r)
{//注意不能是*r。要*&r,由于须要改动r为NULL,防止多次释放
if (r)
{
deleteTree(r->left);
deleteTree(r->right);
delete r; r = NULL;
}
}
};
Geeks 一般二叉树的LCA的更多相关文章
- 二叉树的LCA(最近公共祖先)算法
1.如果是二叉搜索树 2.如果是普通树
- 最近公共祖先问题 LCA
2018-03-10 18:04:55 在图论和计算机科学中,最近公共祖先,LCA(Lowest Common Ancestor)是指在一个树或者有向无环图中同时拥有v和w作为后代的最深的节点. 计算 ...
- Leetcode_236. 二叉树的最近公共祖先
求二叉树的LCA code /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *le ...
- 二刷Cracking the Coding Interview(CC150第五版)
第18章---高度难题 1,-------另类加法.实现加法. 另类加法 参与人数:327时间限制:3秒空间限制:32768K 算法知识视频讲解 题目描述 请编写一个函数,将两个数字相加.不得使用+或 ...
- 【Leetcode】查找二叉树中任意结点的最近公共祖先(LCA问题)
寻找最近公共祖先,示例如下: 1 / \ 2 3 / \ / \ 4 5 6 7 / \ ...
- PAT A1151 LCA in a Binary Tree (30 分)——二叉树,最小公共祖先(lca)
The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...
- 面试题6:二叉树最近公共节点(LCA)《leetcode236》
Lowest Common Ancestor of a Binary Tree(二叉树的最近公共父亲节点) Given a binary tree, find the lowest common an ...
- PAT 1151 LCA in a Binary Tree[难][二叉树]
1151 LCA in a Binary Tree (30 分) The lowest common ancestor (LCA) of two nodes U and V in a tree is ...
- Geeks LCA最低公共单亲节点
给出一颗二叉树.找到两个值的最小公共节点. 假设两个值都会在树中出现. 假设可能不会出现的话,也非常easy.就查找一遍看两个值是否在树中就能够了.假设不在就直接返回NULL. 基本思想:就是在二叉树 ...
随机推荐
- java基础61 JavaScript循环语句之while、do...while、for及for...in循环(网页知识)
本文知识点(目录): 1.while循环语句 2.do...while循环语句 3.for循环语句 4.for...in循环语句 5.附录1(with语句) 6.附录2( ...
- volatile 学习笔记
全面理解Java内存模型(JMM)及volatile关键字 正确使用 Volatile 变量 Java内存模型 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步.通信是指线程之间 ...
- getch与getchar区别
getch(): 所在头文件:conio.h 函数用途:从控制台读取一个字符,但不显示在屏幕上 getchar(): 所在头文件:stdio.h getch与getchar基本功能相同,差别是getc ...
- Pytest里,mark装饰器的使用,双引号,没引号,这种差别很重要
按最新版的pytest测试框架. 如果只是单一的mark,不要加任何引号. 如果是要作and ,not之类的先把,一定要是双引号! 这个要记清楚,好像和以前版本的书上介绍的不一样,切记! import ...
- codeforces 354 D. Transferring Pyramid
D. Transferring Pyramid time limit per test 3 seconds memory limit per test 256 megabytes input stan ...
- linux开启端口
开放端口的方法: 方法一:命令行方式 1. 开放端口命令: /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT ...
- Git配置用户名密码
配置Git 在Linux下和windows下配置Git的方法差不多,只是在Linux下,可以在命令行里直接使用git config进行配置, 而在windows下则要先打开“Git Bash”,进入m ...
- 牛客练习赛3 B - 贝伦卡斯泰露
链接:https://www.nowcoder.net/acm/contest/13/B来源:牛客网 题目描述 贝伦卡斯泰露,某种程度上也可以称为古手梨花,能够创造几率近乎 为0的奇迹,通过无限轮回成 ...
- 在控制台连接oracle
Microsoft Windows [版本 6.1.7601]版权所有 (c) 2009 Microsoft Corporation.保留所有权利. C:\Users\lijt>sqlplus ...
- Javap -c 字节码解析
栈和局部变量操作 将常量压入栈的指令 aconst_null 将null对象引用压入栈 iconst_m1 将int类型常量-1压入栈 icon ...