Lowest common ancestor in binary search tree
2014-09-01 16:20
381 查看
This is a very common question, I write this just for review. Because it is binary search tree. So we can use binary search tree's property to solve the problem.
Solution: Assume the two nodes are n1 and n2 and n1 < n2, n is the lca to be found. if we n1 < n < n2 , then n is the lca. Otherwise recursively traverse the BST to find when n1
< n < n2. If n is greater than both n1 and n2, then lca lies on left subtree of n. If n is smaller than both n1 and n2, then lca lies on right subtree of n. Assuming both n1 and n2 are in the BST.
Consider the below BST for an example:
Below is cpp code to get the lca of this bst:
Below is c code for reference:
reference: Lowest Common Ancestor in a Binary Search Tree.
Solution: Assume the two nodes are n1 and n2 and n1 < n2, n is the lca to be found. if we n1 < n < n2 , then n is the lca. Otherwise recursively traverse the BST to find when n1
< n < n2. If n is greater than both n1 and n2, then lca lies on left subtree of n. If n is smaller than both n1 and n2, then lca lies on right subtree of n. Assuming both n1 and n2 are in the BST.
Consider the below BST for an example:
Below is cpp code to get the lca of this bst:
</pre><pre name="code" class="cpp">#include <iostream> using namespace std; template <class T> class BST; template <class T> class BSTNode // binary search tree node definition { friend class BST<T>; private: BSTNode<T> *leftChild; // left child BSTNode<T> *rightChild; // right child T data; // data domain public: BSTNode() : leftChild(NULL), rightChild(NULL) {} // constructor BSTNode(const T item) : data(item), leftChild(NULL), rightChild(NULL) {} // constructor BSTNode(const T item, BSTNode<T> *left, BSTNode<T> *right) : data(item), leftChild(left), rightChild(right) {} T getData() const { return data; } // get data BSTNode<T>* getLeft() const { return leftChild; } // get left child BSTNode<T>* getRight() const { return rightChild; } // get right child ~BSTNode() {} }; template <class T> class BST // binary search tree class definition { private: BSTNode<T> *root; // root node void insert(const T &x, BSTNode<T> * &ptr); // insert node to the tree void insert_iter(const T &x, BSTNode<T> * &ptr); T lca(BSTNode<T> *ptr, T a, T b); // return the lowest common ancester of node data between a and b T lca_iter(BSTNode<T> *ptr, T a, T b); // iterative way to find lca bool find(T x, BSTNode<T> *ptr); // find node in the binary search tree bool find_iter(T x, BSTNode<T> *ptr); // find node in bst iterative way public: BST<T>() : root(NULL) {} // constructor void insert(const T &x) { insert_iter(x, root); } void insert(BSTNode<T> *ptr); void traverse(BSTNode<T> *current); void traverse() { traverse(root); } T lca(T a, T b) { return lca_iter(root, a, b); } bool find(T x) { return find_iter(x, root); } }; template <class T> void BST<T>::insert(const T &x, BSTNode<T> * &ptr) { if (ptr == NULL) { ptr = new BSTNode<T>(x); if (ptr == NULL) { cerr << "Out of space" << endl; exit(1); } } else if (x < ptr->data) insert(x, ptr->leftChild); else if (x > ptr->data) insert(x, ptr->rightChild); } template <class T> void BST<T>::insert_iter(const T &x, BSTNode<T> * &ptr) { if (ptr == NULL) { ptr = new BSTNode<T>(x); return; } else { BSTNode<T> *temp = ptr; while (true) { if (temp->data == x) { return; } else if (x < temp->data) { if (temp->leftChild == NULL) { temp->leftChild = new BSTNode<T>(x); return; } else { temp = temp->leftChild; } } else if (x > temp->data) { if (temp->rightChild == NULL) { temp->rightChild = new BSTNode<T>(x); return; } else { temp = temp->rightChild; } } } } } template <class T> void BST<T>::insert(BSTNode<T> *ptr) { BSTNode<T> *p = NULL; if (NULL == root) { root = ptr; return; } else { p = root; } while (true) { if (ptr->getData() == p->getData()) return; else if (ptr->getData() < p->getData()) { if (p->getLeft() == NULL) { p->leftChild = ptr; return; } else { p = p->getLeft(); } } else { if (p->getRight() == NULL) { p->rightChild = ptr; return; } else { p = p->getRight(); } } } } template <class T> void BST<T>::traverse(BSTNode<T> *current) { if (current != NULL) { cout << current->data << " "; traverse(current->leftChild); traverse(current->rightChild); } } template <class T> T BST<T>::lca(BSTNode<T> *ptr, T a, T b) { //if (ptr == NULL) return T(NULL); //if (ptr->data > a && ptr->data > b) //{ // return lca(ptr->leftChild, a, b); //} //if (ptr->data < a && ptr->data < b) //{ // return lca(ptr->rightChild, a, b); //} //return ptr->data; if (!find(a) || !find(b)) return T(NULL); // if a or b not in the bst, return default value. if (ptr == NULL) return T(NULL); // if a and b are not in the tree or a == b then return default value of type T. if (a > b) { T temp = a; a = b; b = temp; } // if a > b then swap them first. if (ptr->data > a && ptr->data < b) return ptr->getData(); else if (ptr->data > a && ptr->data > b) return lca(ptr->leftChild, a, b); else return lca(ptr->rightChild, a, b); } template <class T> T BST<T>::lca_iter(BSTNode<T> *ptr, T a, T b) { if (!find(a) || !find(b)) return T(NULL); // if a or b not in the bst, return default value. if (ptr == NULL) return T(NULL); // if a and b are not in the tree or a == b then return default value of type T. if (a > b) { T temp = a; a = b; b = temp; } // if a > b then swap them first. BSTNode<T> *temp = ptr; while (temp != NULL) { if (temp->data > a && temp->data > b) { temp = temp->leftChild; } else if (temp->data < a && temp->data < b) { temp = temp->rightChild; } else { break; } } return temp->getData(); } template <class T> bool BST<T>::find(T x, BSTNode<T> *ptr) { if (ptr == NULL) return false; else if (x < ptr->data) return find(x, ptr->leftChild); else if (x > ptr->data) return find(x, ptr->rightChild); else return true; } template <class T> bool BST<T>::find_iter(T x, BSTNode<T> *ptr) { if (ptr != NULL) { BSTNode<T> *temp = ptr; while (temp != NULL) { if (temp->data == x) return true; else if (temp->data > x) temp = temp->leftChild; else temp = temp->rightChild; } } return false; } int main() { cout << "Hello world!" << endl; BST<int> *b = new BST<int>(); b->insert(20); b->insert(8); b->insert(22); b->insert(4); b->insert(12); b->insert(10); b->insert(14); b->traverse(); cout << endl; int anc = b->lca(14, 4); cout << anc << endl; /*BSTNode<int> *node = new BSTNode<int>(1); b->insert(node);*/ getchar(); return 0; }
Below is c code for reference:
#include <stdio.h> #include <stdlib.h> struct node { int data; struct node *left, *right; }; struct node* newNode(int data) { struct node* node = (struct node*)malloc(sizeof(struct node)); node->data = data; node->left = node->right = NULL; return node; } /* function to find LCA of n1 and n2. The function assumes that both n1 and n2 are present */ struct node* lca(struct node* root, int n1, int n2) { if (root == NULL) return NULL; // if both n1 and n2 are smaller that root, then LCA lies in root's left subtree if (root->data > n1 && root->data > n2) { return lca(root->left, n1, n2); } // if both n1 and n2 are greater than root, then LCA lies in root's right subtree if (root->data < n1 && root->data < n2) { return lca(root->right, n1, n2); } return root; } struct node* lca_iter(struct node* root, int n1, int n2) { if (root == NULL) return NULL; while (root != NULL) { if (root->data > n1 && root->data > n2) { root = root->left; } else if (root->data < n1 && root->data < n2) { root = root->right; } else { break; } } return root; } int main() { struct node *root = newNode(20); root->left = newNode(8); root->right = newNode(22); root->left->left = newNode(4); root->left->right = newNode(12); root->left->right->left = newNode(10); root->left->right->right = newNode(14); int n1 = 10, n2 = 14; struct node *t = lca_iter(root, n1, n2); printf("LCA of %d and %d is %d \n", n1, n2, t->data); n1 = 14, n2 = 8; t = lca_iter(root, n1, n2); printf("LCA of %d and %d is %d \n", n1, n2, t->data); n1 = 10, n2 = 22; t = lca_iter(root, n1, n2); printf("LCA of %d and %d is %d \n", n1, n2, t->data); getchar(); //system("pause"); return 0; }
reference: Lowest Common Ancestor in a Binary Search Tree.
相关文章推荐
- Lowest Common Ancestor in a Binary Search Tree.
- [geeksforgeeks] Lowest Common Ancestor in a Binary Search Tree.
- leetcode 235. Lowest Common Ancestor of a Binary Search Tree
- [LeetCode]235.Lowest Common Ancestor of a Binary Search Tree
- LeetCode:Lowest Common Ancestor of a Binary Search Tree
- Lowest Common Ancestor in a Binary Tree
- [LeetCode]Lowest Common Ancestor of a Binary Search Tree
- Lowest Common Ancestor of a Binary Search Tree
- 235. Lowest Common Ancestor of a Binary Search Tree
- [leetcode] Lowest Common Ancestor of a Binary Search Tree
- 235. Lowest Common Ancestor of a Binary Search Tree
- [Leetocde]Lowest Common Ancestor of a Binary Search Tree
- 235. Lowest Common Ancestor of a Binary Search Tree
- LeetCode 235 Lowest Common Ancestor of a Binary Search Tree
- LeetCode题解:Lowest Common Ancestor of a Binary Search Tree
- Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
- Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
- 235. Lowest Common Ancestor of a Binary Search Tree
- LeetCode 235 Lowest Common Ancestor of a Binary Search Tree(二叉搜索树的最小公共祖先)
- 235. Lowest Common Ancestor of a Binary Search Tree