Skip to content

Commit

Permalink
Add feature get_parent_node
Browse files Browse the repository at this point in the history
  • Loading branch information
DechinPhy committed May 21, 2020
1 parent a34fb08 commit 12455b3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 93 deletions.
109 changes: 38 additions & 71 deletions binarytree/__init__.py
Expand Up @@ -14,7 +14,6 @@
NodeModifyError,
NodeNotFoundError,
NodeReferenceError,
WtreeUnsetError,
)


Expand Down Expand Up @@ -315,7 +314,7 @@ def _get_tree_properties(root):
}


def _get_parent_node(root, node):
def get_parent_node(root, node):
"""Search from the binary tree and return the parent node for require node.
:param root: Root node of the binary tree.
Expand All @@ -324,27 +323,46 @@ def _get_parent_node(root, node):
:rtype: binarytree.Node
:return: The parent node of require node.
:rtype: binarytree.Node
**Example**:
.. doctest::
>>> from binarytree import Node, get_parent_node
>>> root = Node(0)
>>> root.left = Node(1)
>>> root.right = Node(2)
>>> root.left.left = Node(3)
>>> print (root)
>>> 0
/ \
1 2
/
3
>>> print (get_parent_node(root, root.left.left))
>>> 1
/
3
"""
root_height = root.height
node_height = node.height
if root_height == node_height:
if root is node or root is None or node is None:
return None
node_level_list = root.levels[root_height - node_height]
parent_level_list = root.levels[root_height - node_height - 1]
node_index = 0
for index in range(len(node_level_list)):
if node_level_list[index].value == node.value:
node_index = index
node_stack = []
while True:
if root is not None:
node_stack.append(root)
if root.left is node:
return root
else:
root = root.left
elif len(node_stack) > 0:
root = node_stack.pop()
if root.right is node:
return root
else:
root = root.right
else:
break
start_index = node_index // 2
for pnode in parent_level_list[start_index:]:
try:
if pnode.left.value == node.value or\
pnode.right.value == node.value:
return pnode
except AttributeError:
raise WtreeUnsetError('You should set a tree for the node\
you want')
return None


class Node(object):
Expand Down Expand Up @@ -1064,57 +1082,6 @@ def size(self):
"""
return _get_tree_properties(self)['size']

@property
def wtree(self):
"""Set the input tree as a search space.
"""
return self._root

@wtree.setter
def wtree(self, tree):
"""The setter function for wtree setting.
:param tree: The start root node of the binary tree.
:rtype: binarytree.Node
"""
self._root = tree

@property
def upper(self):
"""Get the parent node from a given tree.
:param tree: The start root node of the binary tree.
:rtype: binarytree.Node
:return: The parent node for this node.
:rtype: binarytree.Node
**Example**:
.. doctest::
>>> from binarytree import Node
>>> root = Node(0)
>>> root.left = Node(1)
>>> root.right = Node(2)
>>> root.left.left = Node(3)
>>> print (root)
>>> 0
/ \
1 2
/
3
>>> root.left.left.wtree = root
>>> print (root.left.left.upper)
>>> 1
/
3
"""
try:
return _get_parent_node(self._root, self)
except AttributeError:
raise WtreeUnsetError('You should set a tree for the node you want\
to search.')

@property
def leaf_count(self):
"""Return the total number of leaf nodes in the binary tree.
Expand Down
4 changes: 0 additions & 4 deletions binarytree/exceptions.py
Expand Up @@ -31,7 +31,3 @@ class NodeValueError(BinaryTreeError):

class TreeHeightError(BinaryTreeError):
"""Tree height was invalid."""


class WtreeUnsetError(BinaryTreeError):
"""The whole tree was unset."""
27 changes: 9 additions & 18 deletions tests/test_tree.py
Expand Up @@ -6,7 +6,7 @@
import pytest

from binarytree import Node, build, tree, bst, heap
from binarytree import _get_parent_node
from binarytree import get_parent_node
from binarytree.exceptions import (
NodeValueError,
NodeIndexError,
Expand All @@ -15,7 +15,6 @@
NodeNotFoundError,
TreeHeightError,
NodeReferenceError,
WtreeUnsetError,
)
from tests.utils import (
builtin_print,
Expand Down Expand Up @@ -887,23 +886,15 @@ def test_heap_float_values():


@pytest.mark.order14
def test_get_upper_node():
def test_get_parent_node():
root = Node(0)
root.left = Node(1)
root.right = Node(2)
root.left.left = Node(3)
root.left.left.wtree = root
assert root.left.left.upper == root.left
root.left.left.upper.wtree = root
assert root.left.left.upper.upper == root
root.wtree = root
assert root.upper is None
with pytest.raises(WtreeUnsetError) as err:
root = root.right.upper
assert str(err.value) == 'You should set a tree for the node you want'
with pytest.raises(WtreeUnsetError) as err:
root = _get_parent_node(root, root.right)
assert str(err.value) == 'You should set a tree for the node you want'
root.right.wtree = root
assert root.right._root == root
assert root.right.wtree == root
root.right.right = Node(4)
assert get_parent_node(root, root.left.left) == root.left
assert get_parent_node(root, root.left) == root
assert get_parent_node(root, root) is None
assert get_parent_node(root, root.right.right) == root.right
assert get_parent_node(root, root.right) == root
assert get_parent_node(root, Node(5)) is None

0 comments on commit 12455b3

Please sign in to comment.