Find Common Ancestor

Problem: find the common ancestor of two nodes in a tree

Given a "tree" pointer pointing to the root node of a tree and the other two pointers to two nodes in the tree. You are expected to write a C++ subroutine to find the common ancestor of the two nodes. In any unexpected condition, your code should return null pointer and avoid crashing.

For example, if the tree is like below, B is the common ancestor of E and G; A is the common ancestor of H and F; D is the common ancestor of D and G.

You are allowed to use recursion but as few as possible. You are NOT allowed to use STL. Please follow the type definitions shown below:

 
 
 
 
// tree node type
typedef struct _Node { char value; struct _Node* left; struct _Node* right; }Node; class CommonNodeFinder { //add any auxiliary code here as you wish. public: inline Node* FindCommonAncestor(Node* tree, Node* node_1, Node* node_2) { //your code here. } }
my solution:

#include <iostream>

template< typename T >

class stack{ 

public:

       struct Node{

              T value;

              Node* next;

       };

public:

       stack()

       {

              phead = NULL;

       }

       virtual ~stack()

       {

              Node* pnode = phead;

              while ( pnode != NULL )

              {

                     phead = phead->next;

                     delete pnode;

                     pnode = phead;

              }           

       }

       void push_back( T value )

       {

              Node* ptempnode = new Node;

              ptempnode->value = value;

              ptempnode->next = phead;

              phead = ptempnode;

       }

       T get( ) const

       {

              return phead->value;

       }

       void pop_up( )

       {

              Node* pnode;

              pnode = phead;  

              phead = phead->next;

              delete pnode;

       }

       bool is_empty( ) const

       {

              if ( phead == NULL )

                     return true;

              else

                     return false;

       }

 

private:

       Node* phead;

};

 

template < typename T >

struct Node

{

       T value;

       Node* left;

       Node* right;

};

 

void visit( Node<char>* p )

{

       std::cout << p->value << std::endl;

}

class CommonNodeFinder

{

public:

       // auxiliary function used for generating tree

       void generate_tree( char tree_serial[] )

       {

              int n = strlen( tree_serial );

              if ( n < 1 )

              {

                     tree_phead = NULL;

                     return;

              }

              Node<char>* node;

              node = new Node<char>;

              node->value = tree_serial[0];

              node->left = generate_child( tree_serial, 1, n );

              node->right = generate_child( tree_serial, 2, n );

              tree_phead = node;

              return;

       }

       // auxiliary function used for generating tree

       Node<char>* generate_child( char tree_serial[], const int& index, const int& length )

       {

              if ( index >= length || tree_serial[index] == ' ' )

                     return NULL;

              Node<char>* node;

              node = new Node<char>;

              node->value = tree_serial[index];

              node->left = generate_child( tree_serial, 2 * index + 1 , length );

              node->right = generate_child( tree_serial, 2 * index + 2, length );

              return node;

       }

       // auxiliary function used for visit the tree

       void pre_order_traverse( Node<char>* pnode, void ( *visit ) ( Node<char>* p ))

       {

              if( pnode != NULL )

              {

                     visit( pnode );

                     pre_order_traverse( pnode->left, visit );

                     pre_order_traverse( pnode->right, visit );

              }

       }

 

       // auxiliary function used for delete the tree

       void delete_tree( Node<char>* pnode )

       {

              if ( pnode != NULL )

              {

                     delete_tree( pnode->left );

                     delete_tree( pnode->right );

                     delete pnode;

              }

       }

       // get the Node by the value

       Node<char>* find_in( char val, Node<char>* root )

       {

              Node<char>* node;

              if( root == NULL )

                     return NULL;

              else if ( root->value == val )

                     return root;

              else if ( ( node = find_in( val, root->left ) ) != NULL )

                     return node;

              else if ( ( node = find_in( val, root->right ) ) != NULL )

                     return node;

              else

                     return NULL;

       }

       //generator the ancestor stack for node in the root

       bool is_belong_to( Node<char>* node, Node<char>* root, stack< Node<char>* >& ancestors )

       {

              if ( root == NULL )

                     return false;

              else if ( node == root )

              {

                     ancestors.push_back( root );

                     return true;

              }

              else if ( is_belong_to( node, root->left, ancestors ) )

              {

                     ancestors.push_back( root );

                     return true;

              }

              else if ( is_belong_to( node, root->right, ancestors ) )

              {

                     ancestors.push_back( root );

                     return true;

              }

              else

                     return false;

       }

 

public:

       Node<char>* tree_phead;

       CommonNodeFinder( )

       {

              tree_phead = NULL;

       }

       virtual ~CommonNodeFinder( )

       {

              delete_tree( tree_phead );

       }

public:

       inline Node<char>* FindCommonAncestor(Node<char>* tree, Node<char>* node_1, Node<char>* node_2)

       {

              stack< Node<char>* > ancestor1;

              stack< Node<char>* > ancestor2;

              is_belong_to( node_1, tree, ancestor1 );

              is_belong_to( node_2, tree, ancestor2 );

              if ( ancestor1.is_empty() )

                     return NULL;

              if ( ancestor2.is_empty() )

                     return NULL;

              Node<char> *a1, *a2, *a;

              a1 = ancestor1.get();

              a2 = ancestor2.get();

              while ( a1 == a2 )

              {

                     a = a1;

                     ancestor1.pop_up();

                     if ( ancestor1.is_empty() )

                            break;

                     ancestor2.pop_up();

                     if ( ancestor2.is_empty() )

                            break;

                     a1 = ancestor1.get();

                     a2 = ancestor2.get();

              }

              return a;

       }

};

// test code

int main ( int argc, char* argv[] )

{

       CommonNodeFinder NodeFinder;

       Node<char>* node1;

       Node<char>* node2;

       Node<char>* node;

 

       NodeFinder.generate_tree( "ABCDE HFG" );

       node1 = NodeFinder.find_in( 'D', NodeFinder.tree_phead );

       node2 = NodeFinder.find_in( 'G', NodeFinder.tree_phead );

       node = NodeFinder.FindCommonAncestor( node1, NodeFinder.tree_phead, node2 );

       if ( node )

              std::cout << node->value << std::endl;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段函数代表什么 public int compareTo(WindowContainer other) { Slog.d("huangbg", Log.getStackTraceString( new Throwable())); Slog.d("huangbg","other = " + other); if (this == other) { Slog.d("huangbg"," compareTo 929"); return 0; } Slog.d("huangbg"," mParent = " + mParent); if (mParent != null && mParent == other.mParent) { Slog.d("huangbg"," compareTo 934"); final WindowList<WindowContainer> list = mParent.mChildren; return list.indexOf(this) > list.indexOf(other) ? 1 : -1; } final LinkedList<WindowContainer> thisParentChain = mTmpChain1; final LinkedList<WindowContainer> otherParentChain = mTmpChain2; try { getParents(thisParentChain); other.getParents(otherParentChain); // Find the common ancestor of both containers. WindowContainer commonAncestor = null; WindowContainer thisTop = thisParentChain.peekLast(); WindowContainer otherTop = otherParentChain.peekLast(); while (thisTop != null && otherTop != null && thisTop == otherTop) { commonAncestor = thisParentChain.removeLast(); otherParentChain.removeLast(); thisTop = thisParentChain.peekLast(); otherTop = otherParentChain.peekLast(); } Slog.d("huangbg"," commonAncestor = " + commonAncestor); // Containers don't belong to the same hierarchy??? if (commonAncestor == null) { throw new IllegalArgumentException("No in the same hierarchy this=" + thisParentChain + " other=" + otherParentChain); } // Children are always considered greater than their parents, so if one of the containers // we are comparing it the parent of the other then whichever is the child is greater. if (commonAncestor == this) { Slog.d("huangbg"," compareTo 965"); return -1; } else if (commonAncestor == other) { Slog.d("huangbg"," compareTo 968"); return 1; } Slog.d("huangbg"," compareTo 971"); // The position of the first non-common ancestor in the common ancestor list determines // which is greater the which. final WindowList<WindowContainer> list = commonAncestor.mChildren; return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast()) ? 1 : -1; } finally { mTmpChain1.clear(); mTmpChain2.clear(); } }
02-07

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值