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

时间: 2024-10-08 10:49:23

Geeks 一般二叉树的LCA的相关文章

LCA问题

LCA问题第一弹 上篇文章讲到 区间最值 RMQ 问题,今天,我们来研究一下 LCA 问题. LCA( Least Common Ancestor)问题:中文名为" 最近公共祖先"问题.LCA问题定义是这样的:在一个树形结构中,求解两个子节点的公共祖先中离根节点最远的那个祖先节点,换言之,分别从两个子节点开始向根节点遍历,两条路径最早交汇节点就是最近公共祖先. 为了给大家更加形象的展示一下LCA到底是什么,我用尽毕生力气画了一棵非常不美观的树,希望大家摒弃丑陋的外表来看这棵树.示例如下

Geeks LCA最低公共单亲节点

给出一颗二叉树,找到两个值的最小公共节点. 假设两个值都会在树中出现.如果可能不会出现的话,也很简单,就查找一遍看两个值是否在树中就可以了.如果不在就直接返回NULL. 基本思想:就是在二叉树中比较节点值和两个值的大小,如果都在一边(左边或者右边)那么就往下继续查找,否则就是都在同一边了,那么就可以返回这个节点了,这个节点就是最低公共单亲节点了. 参考:http://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-t

二叉树---最近公共父节点(LCA)

题目: 给定一棵二叉树,找到两个节点的最近公共父节点(LCA). 最近公共祖先是两个节点的公共的祖先节点且具有最大深度. 4 / 3 7 / 5 6 LCA(3, 5) = 4 LCA(5, 6) = 7 LCA(6, 7) = 7 Java代码: public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) { // write your code here if(root == null||root =

求解二叉树中两个节点的最近公共祖先(LCA)

/************************************************************************/ /* 非递归的方法 下面是一个简单的复杂度为 O(n) 的算法,解决LCA问题 1) 找到从根到n1的路径,并存储在一个向量或数组中. 2)找到从根到n2的路径,并存储在一个向量或数组中. 3) 遍历这两条路径,直到遇到一个不同的节点,则前面的那个即为最低公共祖先. */ /*************************************

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 the deepest node that has both U and V as descendants. Given any two nodes in a binary tree, you are supposed to find their LCA. Input Specification:

LeetCode 236. Lowest Common Ancestor of a Binary Tree(二叉树求两点LCA)

题意:二叉树求两点LCA. /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode* lowestCommonAncestor(TreeNode

二叉树 最近祖先lca + 两个结点的最小路径

http://www.acmerblog.com/distance-between-given-keys-5995.html lca在后序遍历中找, tralian算法还不会,懂了再补充 有了lca就好求路径了,做差而已了. //============================================================================ // Name : TreeNodesDistance.java // Author : GaoTong // Da

寻找二叉树中的最低公共祖先结点----LCA(Lowest Common Ancestor )问题(递归)

转自 剑指Offer之 - 树中两个结点的最低公共祖先 题目: 求树中两个节点的最低公共祖先. 思路一: --如果是二叉树,而且是二叉搜索树,那么是可以找到公共节点的. 二叉搜索树都是排序过的,位于左子树的节点都比父节点小,而位于右子树上面的节点都比父节点大. 如果当前节点的值比两个结点 的值都大,那么最低的共同的父节点一定是在当前节点的左子树中,于是下一步遍历当前节点的左子节点. 如果当前节点的值比两个结点的值都小,那么最低的共同的父节点一定是在当前节点的右子树中,于是下一步遍历当前节点的右子

三、二叉树

一.递归思想:递归的基本思想是把规模大的问题转化为规模小的相似的子问题来解决.在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况.另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了.(http://www.nowamagic.net/librarys/veda/detail/2314) 1)遍历:结果在调用时作为参数传递:从顶到下的过程 2)分治:结果在返回值里,不在调用中作为参数传递,从下到上(有递.无归) 同:递归思