-
Notifications
You must be signed in to change notification settings - Fork 312
Added LCA and tests #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
36de7f2
b894bce
8dd5d23
814daad
f9099ba
994e267
94817e0
a53d277
00ad7f7
f997c53
3fa3760
e37ee7d
94d879c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -415,6 +415,107 @@ def rank(self, x): | |
walk = p | ||
return r | ||
|
||
def _simple_path(self, key, root, path): | ||
""" | ||
Utility funtion to find the simple path between root and node. | ||
""" | ||
if root is None: | ||
return False | ||
path.append(root) | ||
if self.tree[root].key == key: | ||
return True | ||
|
||
if self._simple_path(key, self.tree[root].left, path) or \ | ||
self._simple_path(key, self.tree[root].right, path): | ||
path.append(root) | ||
return True | ||
|
||
path.pop() | ||
return False | ||
|
||
def simple_path(self, key): | ||
path = [] | ||
self._simple_path(key, self.root_idx, path) | ||
return path | ||
czgdp1807 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def lowest_common_ancestor(self, j, k, algorithm=1): | ||
|
||
""" | ||
Computes the lowest common ancestor of two nodes. | ||
|
||
Parameters | ||
========== | ||
|
||
j: Node.key | ||
key of first node | ||
k: Node.key | ||
key of second node | ||
algorithm: int | ||
The algorithm to be used for computing the | ||
lowest common ancestor. | ||
Optional, by default uses algorithm 1. | ||
|
||
1 -> Determines the lowest common ancestor by finding | ||
the first intersection of the paths from v and w | ||
to the root. | ||
|
||
2 -> Modifed version of the algorithm given in the | ||
following publication, | ||
D. Harel. A linear time algorithm for the | ||
lowest common ancestors problem. In 21s | ||
Annual Symposium On Foundations of | ||
Computer Science, pages 308-319, 1980. | ||
|
||
Returns | ||
======= | ||
|
||
int | ||
The index of the lowest common ancestor in the tree. | ||
czgdp1807 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if both the nodes are present in the tree. | ||
None | ||
In all other cases. | ||
|
||
References | ||
========== | ||
|
||
.. [1] https://en.wikipedia.org/wiki/Lowest_common_ancestor | ||
|
||
.. [2] https://pdfs.semanticscholar.org/e75b/386cc554214aa0ebd6bd6dbdd0e490da3739.pdf | ||
|
||
""" | ||
if algorithm == 1: | ||
curr_root = self.root_idx | ||
u, v = self.search(j), self.search(k) | ||
if (u is None) or (v is None): | ||
return None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A value error would have been better to let the user know that they are searching for garbage values. |
||
u_left = self.comparator(self.tree[u].key, self.tree[curr_root].key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||
v_left = self.comparator(self.tree[v].key, self.tree[curr_root].key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||
while not (u_left ^ v_left): | ||
if u_left and v_left: | ||
curr_root = self.tree[curr_root].left | ||
else: | ||
curr_root = self.tree[curr_root].right | ||
if curr_root == u or curr_root == v: | ||
return curr_root | ||
u_left = self.comparator(self.tree[u].key, self.tree[curr_root].key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please split this into two lines. Doesn't look clean. |
||
v_left = self.comparator(self.tree[v].key, self.tree[curr_root].key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||
return curr_root | ||
else: | ||
root = self.root_idx | ||
path1 = self.simple_path(j) | ||
path2 = self.simple_path(k) | ||
if not path1 or not path2: | ||
return None | ||
|
||
n, m = len(path1), len(path2) | ||
i = j = 0 | ||
while i < n and j < m: | ||
if path1[i] != path2[j]: | ||
return path1[i - 1] | ||
i += 1 | ||
j += 1 | ||
return None | ||
|
||
class AVLTree(BinarySearchTree): | ||
""" | ||
Represents AVL trees. | ||
|
Uh oh!
There was an error while loading. Please reload this page.