-
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 5 commits
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,126 @@ 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): | ||
return True | ||
|
||
path.pop() | ||
return False | ||
|
||
def simple_path(self, key): | ||
""" | ||
Return the intermediate nodes between root and node with given key | ||
|
||
Parameters | ||
========== | ||
|
||
key: Node.key | ||
key of the node for which path to be found | ||
|
||
Returns | ||
======= | ||
|
||
list | ||
czgdp1807 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
List of intermediate nodes. | ||
Empty list if node is not present. | ||
|
||
""" | ||
path = [] | ||
czgdp1807 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self._simple_path(key, self.root_idx, path) | ||
return path | ||
|
||
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) | ||
print(path1, path2) | ||
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 | ||
if path1 < path2: | ||
return path1[-1] | ||
return path2[-1] | ||
|
||
class AVLTree(BinarySearchTree): | ||
""" | ||
Represents AVL trees. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please convert this into iterative logic using
pydatastructs.Stack
as Python has a finite recursion limit irrespective of the size of heap memory.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stack hasn't been implemented yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I made all the changes you have mentioned except this.
pydatastruct.stack is still abstract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See, https://github.com/codezonediitj/pydatastructs/blob/master/pydatastructs/miscellaneous_data_structures/stack.py#L9
Stack
can be used to remove recursion here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just now saw that.
Ill start making the changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.