(算法)二叉树中两个结点的最近公共父结点
题目:
二叉树中两个结点的最近公共父结点
二叉树结点的定义如下:
struct TreeNode{ int val; TreeNode *left; TreeNode *right; };
思路:
前面在剑指Offer中出现了类似的题目,但要求的思路都不太一样,请参考:http://www.cnblogs.com/AndyJee/p/4693045.html。
这里介绍一种复杂度较低的递归实现。
如题我们要找的二叉树中两个结点的最近公共结点,如果我们从上往下递归,按照深度优先搜索的方式。
如果当前结点为空,即遍历到了叶子结点,直接返回NULL;
如果当前结点等于两个结点之一,那么返回该结点;(因为是从上往下遍历,说明上面的结点都还没找到这两个结点)
如果上面两种情况都不满足,那么两个结点必然存在当前结点的左子树或者右子树或者左右子树当中。
递归遍历左子树,得到pLeft;
递归遍历右子树,得到pRight;
如果pLeft==NULL,则返回pRight;
如果pRight==NULL,则返回pLeft;
如果pLeft,pRight都不为NULL,则返回pRoot;
(先从上往下遍历,再从下往上回溯)
代码:
#include <iostream> #include <fstream> #include <ctime> #include <random> using namespace std; struct TreeNode{ int val; TreeNode *left; TreeNode *right; }; void CreateBiTree(TreeNode *&pNode,fstream &fin,TreeNode *&pNodeOne,TreeNode *&pNodeTwo){ int dat; fin>>dat; if(dat==0) pNode==NULL; else{ pNode=new TreeNode(); pNode->val=dat; if(pNodeOne==NULL && !(rand()%3)) pNodeOne=pNode; if(pNodeTwo==NULL && !(rand()%5)) pNodeTwo=pNode; CreateBiTree(pNode->left,fin,pNodeOne,pNodeTwo); CreateBiTree(pNode->right,fin,pNodeOne,pNodeTwo); } } TreeNode* FindFirstCommonParentNode(TreeNode* pRoot,TreeNode* pNodeOne,TreeNode* pNodeTwo){ if(pRoot==NULL) return NULL; if(pRoot==pNodeOne || pRoot==pNodeTwo) return pRoot; TreeNode* pLeft; TreeNode* pRight; pLeft=FindFirstCommonParentNode(pRoot->left,pNodeOne,pNodeTwo); pRight=FindFirstCommonParentNode(pRoot->right,pNodeOne,pNodeTwo); if(pLeft==NULL) return pRight; else if(pRight==NULL) return pLeft; else return pRoot; } int main(){ srand((unsigned)time(NULL)); fstream fin("tree.txt"); TreeNode *pRoot=NULL; TreeNode *pNodeOne=NULL; TreeNode *pNodeTwo=NULL; CreateBiTree(pRoot,fin,pNodeOne,pNodeTwo); cout<<"First Node is: "<<pNodeOne->val<<endl; cout<<"Second Node is: "<<pNodeTwo->val<<endl; TreeNode *pParent=NULL; pParent=FindFirstCommonParentNode(pRoot,pNodeOne,pNodeTwo); cout<<"First Common Parent Node is: "<<pParent->val<<endl; cout<<endl; return 0; }