The most recent common ancestor (LCA) of a binary tree

1. What is the most recent common ancestor?

LCA is the abbreviation of Lowest Common Ancestor.
For two nodes u, v of a rooted tree T, the nearest common ancestor LCA (T, u, v) represents a node x.
Insert image description here
LCA(5,6) = 2
LCA(7,12) = 3
LCA(2,1)=1

2. Simple solution of common ancestors

  1. The two nodes are first adjusted to the same depth
  2. Each time two points jump up one level at the same time, when the two points meet, it is the LCA of the two points.
    For a set of queries, the time complexity is O(N)

Insert image description here
It requires deep traversal and then constructs such a table

Insert image description here
Assume that LCA(D,G) is found.
The first step: first determine that the depth of D is 3 and the depth of G is 1.
The second step is to move D one step up according to the parent node array, which is node B.
The third step: At this time, the depth B is still different between 2 and 1. You need to continue upward, that is, A. At this time, the depths of A and G are consistent. Step 4:
Determine whether the parent node of A and the parent node of G are consistent. If they are consistent, find it. If they are inconsistent, they will be raised one step at the same time, and this cycle will continue until the two parent nodes are the same for the first time.

3. Recursive solution

There are the following pictures

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Insert image description here

Insert image description here

4. Code

The following code constructs the following tree, and implements the naive method and the recursive method respectively.

Insert image description here

#include<iostream>
using namespace std;
using ElemType = char;

typedef struct BiTNode
{
    
    
	ElemType data;
	int nIndex;
	struct BiTNode* lchild;
	struct BiTNode* rchild;

}BiTNode, * BiTree;

int arrayD[100] = {
    
     -1 };
int arrayF[100] = {
    
     -1 };
void DFS(BiTNode* tree, int nd, int nf)
{
    
    
	if (tree)
	{
    
    
		DFS(tree->lchild, nd + 1, tree->nIndex);
		arrayD[tree->nIndex] = nd;
		arrayF[tree->nIndex] = nf;
		DFS(tree->rchild, nd + 1, tree->nIndex);
	}
}

int LCA1(int u, int v)
{
    
    
	if (arrayD[u] < arrayD[v])
	{
    
    
		swap(u, v);
	}

	if (arrayD[u] > arrayD[v] && arrayF[u] != v)
	{
    
    
		while (arrayD[u] != arrayD[v])
		{
    
    
			u = arrayF[u];
		}

		while (arrayF[u] != arrayF[v])
		{
    
    
			u = arrayF[u];
			v = arrayF[v];
		}

	}

	return arrayF[u];

}

BiTNode* LCA2(BiTNode *pRoot,BiTNode *p,BiTNode *q)
{
    
    
	if (pRoot == p|| pRoot == q || pRoot == NULL)
	{
    
    
		return pRoot;
	}

	BiTNode* pLeft = LCA2(pRoot->lchild, p, q);
	BiTNode* pRight = LCA2(pRoot->rchild, p, q);

	if (pLeft && pRight)
	{
    
    
		return pRoot;
	}
	else if (pLeft)
	{
    
    
		return pLeft;
	}
	else if (pRight)
	{
    
    
		return pRight;
	}
	else
	{
    
    
		return NULL;
	}
}

int main()
{
    
    

	BiTNode b1, b2, b3, b4, b5, b6, b7;
	memset(&b1, 0, sizeof(BiTNode));
	memset(&b2, 0, sizeof(BiTNode));
	memset(&b3, 0, sizeof(BiTNode));
	memset(&b4, 0, sizeof(BiTNode));
	memset(&b5, 0, sizeof(BiTNode));
	memset(&b6, 0, sizeof(BiTNode));
	memset(&b7, 0, sizeof(BiTNode));

	b1.nIndex = 0; b1.data = 'A';
	b2.nIndex = 1; b2.data = 'B';
	b3.nIndex = 2; b3.data = 'C';
	b4.nIndex = 3; b4.data = 'D';
	b5.nIndex = 4; b5.data = 'E';
	b6.nIndex = 5; b6.data = 'F';
	b7.nIndex = 6; b7.data = 'G';
	//构建树关系
	b1.lchild = &b2;
	b1.rchild = &b3;
	b2.lchild = &b4;
	b2.rchild = &b5;

//根
b6.lchild = &b1;
b6.rchild = &b7;


cout << "LCA1:\n";
	DFS(&b6, 0, -1);

	int nIndex = LCA1(b1.nIndex, b2.nIndex);
	if (nIndex >= 0)
	{
    
    
		printf("LCA(%c,%c)= index(%d)\n", b1.data, b2.data, nIndex);
	}

	nIndex = LCA1(b5.nIndex, b7.nIndex);
	if (nIndex >= 0)
	{
    
    
		printf("LCA(%c,%c)= index(%d)\n", b5.data, b7.data, nIndex);
	}
	
	//LCA2
	cout << "LCA2:\n";

	BiTNode *pLCA = LCA2(&b6, &b1, &b2);
	if (pLCA)
	{
    
    
		printf("LCA(%c,%c)= %c\n",b1.data,b2.data, pLCA->data);
	}

	pLCA = LCA2(&b6, &b5, &b7);
	if (pLCA)
	{
    
    
		printf("LCA(%c,%c)= %c\n", b5.data, b7.data, pLCA->data);
	}
	system("pause");
}

result:
Insert image description here

Guess you like

Origin blog.csdn.net/FairLikeSnow/article/details/131118217