二叉树中两个节点的最近公共父节点

  • 情况一:root未知,但是每个节点都有parent指针

解决方法是求出linkedList A的长度lengthA, linkedList B的长度LengthB。然后让长的那个链表走过abs(lengthA-lengthB)步之后,齐头并进,相遇的节点就是最近公共父节点。

template <class T>
int getLength(BinaryTreeNode<T>* pNode)
{      
	int length = 0;
	BinaryTreeNode<T>* pTemp = pNode;
	while (pTemp)
	{
		length++ ;   
		pTemp = pTemp->pParent; 
	}
	return length;   
 }

template <class T>
BinaryTreeNode<T>* findLCACase1(BinaryTreeNode<T>* pNode1, BinaryTreeNode<T>* pNode2)
{
	int length1 = getLength(pNode1);
	int length2 = getLength(pNode2);

	// skip the abs(length1-length2)
	BinaryTreeNode<T>* pIter1 = NULL;
	BinaryTreeNode<T>* pIter2 = NULL;
	int k = 0;   
	if (length1>=length2) {   
		bstNode* pTemp = pNode1;
		while (k++ < length1-length2) {
			pTemp = pTemp->pParent;    
		}
		pIter1 = pTemp;
		pIter2 = pNode2;   
	} else {
		BinaryTreeNode* pTemp = pNode1;   
		while (k++ < length2-length1) {
			pTemp = pTemp->pParent;    
		}
		pIter1 = pNode1;
		pIter2 = pTemp;   
	}

	while (pIter1 && pIter2 && pIter1!= pIter2) {
		pIter1 = pIter1->pParent;
		pIter2 = pIter2->pParent;   
	}
	
	return pIter1;   
}
  • 情况二:节点只有left/right,没有parent指针,root已知
template <class T>
bool nodePath(BinaryTreeNode<T>* pRoot, int value, vector<BinaryTreeNode<T>*>& path)   
{   
	if (pRoot==NULL)
		return false;
	if (pRoot->data != value) {
		if (nodePath(pRoot->pLeft, value, path)) {
			path.push_back(pRoot);
			return true;   
		} else if (nodePath(pRoot->pRight, value, path)) {
			path.push_back(pRoot);
			return true;   
		} else
			return false;      
	} else {
		path.push_back(pRoot);
		return true;   
	}
 }

template <class T>
BinaryTreeNode<T>* findLCACase2(BinaryTreeNode<T>* pNode, int value1, int value2)   
{
	std::vector<BinaryTreeNode<T>*> path1;
	std::vector<BinaryTreeNode<T>*> path2;
	bool find = false;
	find |= nodePath(pNode, value1, path1);
	find &= nodePath(pNode, value2, path2);
	BinaryTreeNode<T>* pReturn = NULL;
	if (find) {
		int minSize = path1.size()>path2.size()?path2.size():path1.size();
		int it1 = path1.size()- minSize;
		int it2 = path2.size()- minSize;
		for ( ; it1<path1.size(), it2<path2.size(); it1++, it2++) {
			if (path1[it1]==path2[it2]) {
				pReturn = path1[it1];
				break;   
			}
		}
	}
	return pReturn;   
}
  • 情况三: 二叉树是个二叉查找树,且root和两个节点的值(a, b)已知
BinaryTreeNode<T>* findLCACase3(BinaryTreeNode<T>* pNode, int value1, int value2)   
{
	BinaryTreeNode<T>* pTemp = pNode;
	while (pTemp) {
		if (pTemp->data>value1 && pTemp->data>value2)
			pTemp = pTemp->pLeft;
		else if(pTemp->data<value1 && pTemp->data<value2)
			pTemp = pTemp->pRight;
		else
			return pTemp;   
	}
	return NULL;   
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值