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 ); }
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); }
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; }
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; }
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; }
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; }
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; }