1. 程式人生 > >二叉樹中找兩個結點的最近公共祖先結點

二叉樹中找兩個結點的最近公共祖先結點

一、搜尋二叉樹:第一變種是二叉樹是一種特殊的二叉樹:查詢二叉樹。也就是樹是排序過的,位於左子樹上的結點都比父結點小,而位於右子樹的結點都比父結點大。我們只需要從根結點開始和兩個結點進行比較。如果當前結點的值比兩個結點都大,則最低的共同父結點一定在當前結點的左子樹中。如果當前結點的值比兩個結點都小,則最低的共同父結點一定在當前結點的右子樹中。(4<5 7>5)


二、三叉鏈(可以找到父節點):遍歷4節點到根結點,找出第一個和7結點到根結點這一路徑重合的結點。(分別查詢4、3、5、10是否在7-8-5-10中,因為5最先重合,所以5為4和7祖先結點)


三、普通二叉樹:先序遍歷找出根結點到a、b結點的路徑存入陣列,然後遍歷兩個陣列找到兩個陣列第一次不同的結點的上一個結點。


#pragma once
#include <iostream>
using namespace std;
#include <vector>

struct Node
{
	Node* left;
	Node *right;
	int value;
	Node(int v)
		:left(NULL)
		,right(NULL)
		,value(v)
	{}
};
bool GetPath(Node *root,vector<Node*>&path,Node* x)
{
	if (root == NULL)
	{
		return false;
	}
	path.push_back(root);
	if (root == x)
	{
		return true;
	}
	if (GetPath(root->left, path, x))
	{
		return true;
	}
	if (GetPath(root->right, path, x))
	{
		return true;
	}
	else
	{
		path.pop_back();
		return false;
	}
}
Node* find_common_parent(Node* root, Node* a, Node* b)
{
	if (root == NULL)
	{
		return NULL;
	}
	Node* common_parent = NULL;

	vector<Node *> va, vb;
	GetPath(root, va, a);
	GetPath(root, vb, b);
	size_t i = 0;
	while (i < va.size() && i < vb.size() && va[i] == vb[i])
	{
		common_parent = va[i];
		i++;
	}
	return common_parent;

}