Detailed explanation of the lowest common parent node of the two-fork tree two nodes _c language

Source: Internet
Author: User
Topic: The node of the two fork tree is defined as follows:
Copy Code code as follows:

struct TreeNode
{
int m_nvalue;
treenode* M_pleft;
treenode* M_pright;
};

Enter two nodes in the binary tree to output the lowest common parent node of the two nodes in the number.
Analysis: Finding the lowest common node of two nodes in a number of points is a frequent problem in the interview. There are at least two variants of this problem.
The first variant is a two-fork tree is a special two-fork tree: Looking for a binary tree. That is, the tree is sorted, the node located on the left subtree is smaller than the parent node, and the node in the right subtree is larger than the parent node. We just need to start with the root node and compare two nodes. If the value of the current node is greater than the two nodes, then the lowest common parent node must be in the left subtree of the current node. If the value of the current node is smaller than the two nodes, then the lowest common parent node must be in the right subtree of the current node.
The second variant is that the tree is not necessarily a two-forked tree, and each node has a pointer to its parent node. So we can start from any node and get a one-way list that reaches the root node. So this problem is converted to the first public node for two one-way lists.
Now we go back to the question itself. The so-called common parent node is that two nodes appear in the subtree of this node. So we can define a function to determine whether another node is included in the subtree of a node. This is not a very difficult thing, we can use the recursive method to achieve:
Copy Code code as follows:

/*
If The tree is Phead has a node pnode, return True.
otherwise return false.
*/
BOOL Hasnode (treenode* phead, treenode* pnode)
{
if (Phead = = Pnode)
return true;
BOOL has = false;
if (Phead->m_pleft!= NULL)
has = Hasnode (Phead->m_pleft, Pnode);
if (!has && phead->m_pright!= NULL)
has = Hasnode (Phead->m_pright, Pnode);
return has;
}

We can start with the root node to determine whether the left and right subtree in the tree rooted at the current node contains the two nodes we are looking for. If two nodes appear in its left subtree, the lowest common parent node also appears in its left subtree. If two nodes appear in its right subtree, the lowest common parent node also appears in its right subtree. If two nodes appear in the left subtree and one appears in the right subtree, the current node is the lowest common parent node. Based on this idea, we can write the following code:
Copy Code code as follows:

/*
Find the last parent of PNode1 and PNode2 in A and head phead
*/
treenode* lastcommonparent_1 (treenode* phead, treenode* pNode1, treenode* pNode2)
{
if (Phead = null | | pNode1 = NULL | | | pNode2 = NULL)
return NULL;
Check whether left child has pNode1 and PNode2
BOOL LeftHasNode1 = false;
BOOL LeftHasNode2 = false;
if (Phead->m_pleft!= NULL)
{
LeftHasNode1 = Hasnode (Phead->m_pleft, pNode1);
LeftHasNode2 = Hasnode (Phead->m_pleft, PNode2);
}
if (leftHasNode1 && leftHasNode2)
{
if (Phead->m_pleft = = PNode1 | | phead->m_pleft = = PNODE2)
return phead;
Return lastcommonparent_1 (Phead->m_pleft, PNode1, PNode2);
}
Check whether right child has pNode1 and PNode2
BOOL RightHasNode1 = false;
BOOL RightHasNode2 = false;
if (phead->m_pright!= NULL)
{
if (!LEFTHASNODE1)
RightHasNode1 = Hasnode (Phead->m_pright, pNode1);
if (!LEFTHASNODE2)
RightHasNode2 = Hasnode (Phead->m_pright, PNode2);
}
if (rightHasNode1 && rightHasNode2)
{
if (phead->m_pright = = PNode1 | | phead->m_pright = = PNODE2)
return phead;
Return lastcommonparent_1 (Phead->m_pright, PNode1, PNode2);
}
if ((leftHasNode1 && rightHasNode2) | | (LeftHasNode2 && rightHasNode1))
return phead;
return NULL;
}

Then we will analyze the efficiency of this method. The essence of function hasnode is to traverse a tree whose time complexity is O (n) (n is the number of nodes in the tree). Because we start with a node, call function Hasnode for each node. The total time complexity is therefore O (n^2).
By carefully analyzing the code above, it is not difficult to find out whether a tree with a node as its root contains a node that needs to traverse each node of the tree. Next we judge whether the Zoozi node or the tree with the right node as root contains the node to find, and still need to traverse it. The second traversal is actually done in front of the first traversal. Because of the repeated traversal, this method is certainly not the best in time efficiency.
We mentioned earlier that if there is a pointer to the parent node in the node, we can turn the problem into a common node for two lists. Now we can find a way to get this list. We can change here a little bit:
Copy Code code as follows:

/*
Get the "path form" Phead and Pnode in A and head phead
*/
BOOL Getnodepath (treenode* phead, treenode* pnode, std::list<treenode*>& Path)
{
if (Phead = = Pnode)
return true;
Path.push_back (Phead);
BOOL found = false;
if (Phead->m_pleft!= NULL)
Found = Getnodepath (Phead->m_pleft, Pnode, Path);
if (!found && phead->m_pright)
Found = Getnodepath (phead->m_pright, Pnode, Path);
if (!found)
Path.pop_back ();
return found;
}

Since this path starts with the node. The lowest common parent node is the last common node in the path:
Copy Code code as follows:

/*
Get the last common Node in two lists:path1 and path2
*/
treenode* Lastcommonnode
(
Const std::list<treenode*>& path1,
Const std::list<treenode*>& PATH2
)
{
Std::list<treenode*>::const_iterator Iterator1 = Path1.begin ();
Std::list<treenode*>::const_iterator Iterator2 = Path2.begin ();
treenode* pLast = NULL;
while (Iterator1!= path1.end () && Iterator2!= path2.end ())
{
if (*iterator1 = = *iterator2)
PLast = *iterator1;
iterator1++;
iterator2++;
}
return pLast;
}

With the previous two child functions, it is easy to find the lowest common parent node for two nodes. We first find two paths from the root node to two nodes, and then find the last common node of two paths. The code is as follows:
Copy Code code as follows:

/*
Find the last parent of PNode1 and PNode2 in A and head phead
*/
treenode* lastcommonparent_2 (treenode* phead, treenode* pNode1, treenode* pNode2)
{
if (Phead = null | | pNode1 = NULL | | | pNode2 = NULL)
return NULL;
Std::list<treenode*> path1;
Getnodepath (Phead, PNode1, path1);
Std::list<treenode*> path2;
Getnodepath (Phead, PNode2, path2);
Return Lastcommonnode (path1, path2);
}

The time complexity of this idea is O (n), the time efficiency is much better than the first method. But at the same time we should also note that this kind of thinking requires two linked lists to save the path, space efficiency is not the first method.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.