您的位置:首页 > Web前端 > Node.js

ch4.6: find the LCA of 2 nodes in a binary tree with 3 different methods

2014-01-24 09:43 639 查看
In this problem, it is important to fully understand the definition of least common ancestor of 2 nodes:

it means: (from leetcode blog:
点击打开链接)

_______3______
/              \
___5__          ___1__
/      \        /      \
6      _2       0       8
/  \
7   4


If you are not so sure about the definition of lowest common ancestor (LCA), please refer to my previous post:Lowest
Common Ancestor of a Binary Search Tree (BST) or the definition of LCA here.
Using the tree above as an example, the LCA of nodes 5 and 1 is 3.
Please note that LCA for nodes 5 and 4 is 5.

Here is the whole code with comments. Really good design by Hawstein.

// Ch4.6: Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree.
// Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.

//http://leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html
//the LCA of nodes 5 and 1 is 3. Please note that LCA for nodes 5 and 4 is 5.

#include
#include
#include
#include
using namespace std;

class BinNode{
public:
int key;
BinNode *parent, *lChild, *rChild;
BinNode(){}
BinNode(int t): key(t), parent(NULL), lChild(NULL), rChild(NULL){}
};

class BTree{
private:
BinNode *m_root;
public:
BTree(): m_root(NULL){}
BTree(BinNode *t): m_root(t){}

BinNode* getRoot() const{return m_root;}

BinNode* balanceTree(BinNode* pnode, BinNode *parent, int *arr, int low, int high){
if(low>high || arr == NULL)
return NULL;
int mid = (low+high)>>1;
pnode = new BinNode(arr[mid]);
pnode->parent = parent;
pnode->lChild = balanceTree(pnode->lChild, pnode, arr, low, mid-1);
pnode->rChild = balanceTree(pnode->rChild, pnode, arr, mid+1, high);

return pnode;
}

void PrintPre(BinNode *pnode)
{
if(pnode == NULL)
return;

cout << pnode->key << " ";
PrintPre(pnode->lChild);
PrintPre(pnode->rChild);
}

BinNode* minimal(BinNode* pnode){
if(pnode==NULL) return NULL;
while(pnode->lChild){
pnode = pnode->lChild;
}
return pnode;
}

BinNode* successor(BinNode* qnode){
if(qnode==NULL) return NULL;
if(qnode->rChild) return minimal(qnode->rChild);
BinNode *r = qnode->parent;
while(r && r->rChild==qnode){
qnode = r;
r = r->parent;
}
return r;
}
//  method 1: use a hash table to store the n1's parent to see if n2's parents are
//  in the map. Learn to use map: key: pointer to the value, mapped value: the real data
BinNode* firstAns(BinNode *n1, BinNode *n2){
if(n1==NULL || n2==NULL) return NULL;
map m;
while(n1){
m[n1] = true;
n1=n1->parent;
}
while(n2 && !m[n2]){
n2 = n2->parent;
}
return n2;
}

//  method 2: recursively search for the commen father of (n1,n2).
//  father method is use to see if (n1,n2) share the same father by going down:
//  n1->child->child->...->child. Only modify n1;
//  in the LCA recursively move n1 up 1 step until find (n1->p->p->...->p,n2)
//  the same father. only modify n1;
//  By combining these 2 methods(one goes down, one goes up), n1 will search all the
//  nodes in the tree to find the LCA to n2;
bool father(BinNode *n1, BinNode *n2){
if(n1==NULL || n2==NULL) return false;
else if (n1==n2) return true;
return (father(n1->lChild, n2) || father(n1->rChild, n2));
}

BinNode* firstAns2(BinNode *n1, BinNode *n2){
if (n1==NULL || n2==NULL) return NULL;
while(n1){
if(father(n1,n2)) return n1;
n1=n1->parent;
}
return NULL; // don't forget it.
}

/*  method 3: if the node doesn't contain parent pointer(just don't use ->parent),
then we can start from root and recursively. Carefully read the solution,: how
to update head, res. Use Node* &res, call by reference so will modify ans.
*/
void firstAns3(BinNode *head, BinNode *n1, BinNode *n2, BinNode* &res){
if (head==NULL || n1==NULL || n2==NULL) return;
if(head && father(head, n1) && father(head, n2)){
res = head;
firstAns3(head->lChild, n1, n2, res);
firstAns3(head->rChild, n1, n2, res);
}
}

// Auxilary methods:
BinNode* searchND(BinNode* x_head, int x){
if(x_head==NULL) return NULL;
else if(x==x_head->key) return x_head;
else if(x<=x_head->key) searchND(x_head->lChild, x);
else searchND(x_head->rChild, x);
}

vector> BFSlist(BinNode *head){
vector> res;
int level = 0;
list li;
li.push_back(head);
res.push_back(li);
while(!res[level].empty()){
list l;
list::iterator it;
for(it=res[level].begin(); it!=res[level].end(); ++it){
BinNode *n = *it;
if(n->lChild) l.push_back(n->lChild);
if(n->rChild) l.push_back(n->rChild);
}
++level;
res.push_back(l);
}
return res;
}

void print(vector > res){
vector >::iterator vit;
for(vit=res.begin(); vit!=res.end(); ++vit){
list li = *vit;
list::iterator lit;
for(lit=li.begin(); lit!=li.end(); ++lit){
BinNode *n = *lit;
cout<key<<" ";
}
cout<balanceTree(bt->getRoot(), NULL, arr, low, high);
bt = new BTree(proot);
bt->PrintPre(bt->getRoot());
cout << "pnode is:  "<< proot->key<successor(proot))->key<> jerry = bt->BFSlist(proot);
bt->print(jerry);

BinNode *n1 = bt->searchND(proot, 13);
BinNode *n2 = bt->searchND(proot, 22);
BinNode *n1_n2_ans = bt->firstAns(n1, n2);

cout<key<<" "<key<key<firstAns2(n1, n2);
cout<key<firstAns3(proot, n1, n2, result);
cout<key<
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: