pair <int, struct Node*> findLCA(struct Node* root, int n1, int n2)
{
    // Base case
    if (root == NULL) return make_pair(-1,NULL);
 
    // If either n1 or n2 matches with root's key, report
    // the presence by returning root (Note that if a key is
    // ancestor of other, then the ancestor key becomes LCA
    if (root->key == n1 || root->key == n2)
        return make_pair(1,root);
 
    // Look for keys in left and right subtrees
    pair <int, struct Node*> left_lca  = findLCA(root->left, n1, n2);
    pair <int, struct Node*> right_lca = findLCA(root->right, n1, n2);
 
    // If both of the above calls return Non-NULL, then one key
    // is present in once subtree and other is present in other,
    // So this node is the LCA
    if (left_lca.second && right_lca.second ){
        if( left_lca.first == right_lca.first && right_lca.first!=1)
            //return benar
            return make_pair(left_lca.first+1,left_lca);
    }
 
    // Otherwise check if left subtree or right subtree is LCA
    return (left_lca != /*ga ketemu*/) ? 
        //naik ke atas
        make_pair(left_lca.first + 1, left_lca.second ): 

        make_pair(right_lca+1,right_lca.second );
}
예제 #2
0
tree_node *findLCA(tree_node *root, tree_node *node1, tree_node *node2){
	if(root == NULL) return NULL;
	if(root == node1 || root == node2) return root;
	tree_node *left = findLCA(root->left, node1, node2);
	tree_node *right = findLCA(root->right, node1, node2);
	if(left && right) return root;
	else return (left != NULL ? left : right);
}
예제 #3
0
struct tree *findLCA(struct tree * root, int a, int b)
{
	if(root==NULL) return NULL;
	if(root->data==a || root->data==b)return root;
	struct tree *left=findLCA(root->left,a,b);
	struct tree *right=findLCA(root->right,a,b);
	if( left && right) return root;
	return left?left:right;
}
int main(){
	node * root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    cout << "LCA(4, 5) = " << findLCA(root, 4, 5);
    cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6);
    cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4);
    cout << "\nLCA(2, 4) = " << findLCA(root, 4, 2);
	return 0;
}
//使用递归的方法查找lca,如果结点的左子树与右子树分别包含n1与n2,那么此结点就是lca
//否则lca在子结点中,继续递归进行查找。
BinaryNode* findLCA(BinaryNode *root, int n1, int n2){
    if (root->val == n1 || root->val == n2) {
        return root;
    }
    
    BinaryNode *leftLca = findLCA(root->left, n1, n2);
    BinaryNode *rightLca = findLCA(root->right, n1, n2);
    
    if (leftLca && rightLca) {
        return root;
    }
    
    return leftLca ? leftLca : rightLca;
}
예제 #6
0
bool findArgument(int s)
{
	bool ret = 0;
	memset(tag, 0, sizeof(tag));
	memset(fa, 0, sizeof(fa));
	for (int i = 1; i <= n; i++) f[i] = i;
	queue<int> q;
	q.push(s);
	tag[s] = S;
	while (!q.empty())
	{
		int u = q.front(); q.pop();
		for (int v = 1; v <= n; v++) if (G[u][v] && v != matched[u] && find(u) != find(v) && tag[v] != T)
		{
			if (tag[v] == S) // meet a S node
			{
				int p = findLCA(u, v);
				// important
				if (find(u) != p) fa[u] = v;
				if (find(v) != p) fa[v] = u;
				// important order 
				contract(u, p, q);
				contract(v, p, q);
			}
			else if (!matched[v]) // find a free node
			{
				argument(u, v);
				return 1;
			}
			else // find a matched node
				expand(u, v, q);
		}
	}
	return 0;
}
//计算两个结点距离
int calDistance(BinaryNode *root, int n1, int n2){
    BinaryNode *lca = findLCA(root, n1, n2);
    
    int dst1 = calDis(lca, n1);
    int dst2 = calDis(lca, n2);
    
    return dst1 + dst2;
}
예제 #8
0
    bool LCA::test() {
        vector<int> preOrder1 = {314, 6, BTNULL, 2, BTNULL, 3, BTNULL, BTNULL, 6, 2, 3};
        size_t pos = 0;
        unique_ptr<BinaryTreeNode<int>> root1 = createPreOrderIntBTree(preOrder1, &pos);
        unique_ptr<BinaryTreeNode<int>> &node11 = root1.get()->left;
        unique_ptr<BinaryTreeNode<int>> &node12 = root1.get()->right;

        if (findLCA(node11, node12)->data != 314) {
            cout << "root1 should be common ancestor" << endl;
            return false;
        }

        return true;
    }
예제 #9
0
struct node *findLCA(struct node* root, int n1, int n2)
{
    // Base case
    if (root == NULL) return NULL;
 
    // If either n1 or n2 matches with root's data, report
    // the presence by returning root (Note that if a data is
    // ancestor of other, then the ancestor data becomes LCA
    if (root->data == n1 || root->data == n2)
        return root;
 
    // Look for datas in left and right subtrees
    struct node *left_lca  = findLCA(root->left, n1, n2);
    struct node *right_lca = findLCA(root->right, n1, n2);
 
    // If both of the above calls return Non-NULL, then one data
    // is present in once subtree and other is present in other,
    // So this node is the LCA
    if (left_lca && right_lca)  return root;
 
    // Otherwise check if left subtree or right subtree is LCA
    return (left_lca != NULL)? left_lca: right_lca;
}
예제 #10
0
    bool FindLCA::test() {
        vector<int> preOrder = {19, 7, 3, 2, 5, 11, 17, 13, 43, 23, 37, 29, 31, 41, 47, 53};

        unique_ptr<BSTNode<int>> tree = createBSTFromPreorder(preOrder);
        unique_ptr<BSTNode<int>> &c = tree.get()->left.get()->left;
        unique_ptr<BSTNode<int>> &g = tree.get()->left.get()->right.get()->right;

        int ans = 7;

        BSTNode<int> *res = findLCA(tree, c, g);

        if (res->data != ans) {
            cout << "Should be " << ans << endl;
            cout << "Result " << res->data << endl;

            return false;
        }

        return true;
    }