Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 59 additions & 1 deletion binarytree/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ def _is_bst(root, min_value=float('-inf'), max_value=float('inf')):
)


def _is_symmetric(root):
"""Check if the binary tree is symmetric

:param root: Root node of the binary tree
:type root: binarytree.Node | None
:return: True if the binary tree is symmetric, False otherwise.
:rtype: bool
"""
def symmetric_helper(left_subtree, right_subtree):
if left_subtree is None and right_subtree is None:
return True
if left_subtree is None or right_subtree is None:
return False
return (
left_subtree.value == right_subtree.value and
symmetric_helper(left_subtree.left, right_subtree.right) and
symmetric_helper(left_subtree.right, right_subtree.left)
)
return symmetric_helper(root, root)


def _validate_tree_height(height):
"""Check if the height of the binary tree is valid.

Expand Down Expand Up @@ -1103,6 +1124,40 @@ def is_bst(self):
"""
return _is_bst(self, float('-inf'), float('inf'))

@property
def is_symmetric(self):
"""Check if the binary tree is symmetric.

* Left subtree is a mirror of the right subtree around the center

:return: True if the binary tree is a symmetric, False otherwise.
:rtype: bool

**Example**:

.. doctest::

>>> from binarytree import Node
>>> root = Node(1)
>>> root.left = Node(2)
>>> root.right = Node(2)
>>> root.left.left = Node(3)
>>> root.left.right = Node(4)
>>> root.right.left = Node(4)
>>> root.right.right = Node(3)
>>> print(root)
<BLANKLINE>
__1__
/ \\
2 2
/ \\ / \\
3 4 4 3
<BLANKLINE>
>>> root.is_symmetric
True
"""
return _is_symmetric(self)

@property
def is_max_heap(self):
"""Check if the binary tree is a `max heap`_.
Expand Down Expand Up @@ -1424,6 +1479,8 @@ def properties(self):
False
>>> props['is_complete'] # equivalent to root.is_complete
True
>>> props['is_symmetric'] # equivalent to root.is_symmetric
False
>>> props['is_max_heap'] # equivalent to root.is_max_heap
False
>>> props['is_min_heap'] # equivalent to root.is_min_heap
Expand All @@ -1436,7 +1493,8 @@ def properties(self):
properties = _get_tree_properties(self)
properties.update({
'is_bst': _is_bst(self),
'is_balanced': _is_balanced(self) >= 0
'is_balanced': _is_balanced(self) >= 0,
'is_symmetric': _is_symmetric(self)
})
return properties

Expand Down
15 changes: 15 additions & 0 deletions tests/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ def test_tree_properties():
'is_min_heap': True,
'is_perfect': True,
'is_strict': True,
'is_symmetric': True,
'leaf_count': 1,
'max_leaf_depth': 0,
'max_node_value': 1,
Expand All @@ -429,6 +430,7 @@ def test_tree_properties():
assert root.is_min_heap is True
assert root.is_perfect is True
assert root.is_strict is True
assert root.is_symmetric is True
assert root.leaf_count == 1
assert root.max_leaf_depth == 0
assert root.max_node_value == 1
Expand All @@ -446,6 +448,7 @@ def test_tree_properties():
'is_min_heap': True,
'is_perfect': False,
'is_strict': False,
'is_symmetric': False,
'leaf_count': 1,
'max_leaf_depth': 1,
'max_node_value': 2,
Expand All @@ -461,6 +464,7 @@ def test_tree_properties():
assert root.is_min_heap is True
assert root.is_perfect is False
assert root.is_strict is False
assert root.is_symmetric is False
assert root.leaf_count == 1
assert root.max_leaf_depth == 1
assert root.max_node_value == 2
Expand All @@ -478,6 +482,7 @@ def test_tree_properties():
'is_min_heap': True,
'is_perfect': True,
'is_strict': True,
'is_symmetric': False,
'leaf_count': 2,
'max_leaf_depth': 1,
'max_node_value': 3,
Expand All @@ -493,6 +498,7 @@ def test_tree_properties():
assert root.is_min_heap is True
assert root.is_perfect is True
assert root.is_strict is True
assert root.is_symmetric is False
assert root.leaf_count == 2
assert root.max_leaf_depth == 1
assert root.max_node_value == 3
Expand All @@ -510,6 +516,7 @@ def test_tree_properties():
'is_min_heap': True,
'is_perfect': False,
'is_strict': False,
'is_symmetric': False,
'leaf_count': 2,
'max_leaf_depth': 2,
'max_node_value': 4,
Expand All @@ -525,6 +532,7 @@ def test_tree_properties():
assert root.is_min_heap is True
assert root.is_perfect is False
assert root.is_strict is False
assert root.is_symmetric is False
assert root.leaf_count == 2
assert root.max_leaf_depth == 2
assert root.max_node_value == 4
Expand All @@ -542,6 +550,7 @@ def test_tree_properties():
'is_min_heap': False,
'is_perfect': False,
'is_strict': False,
'is_symmetric': False,
'leaf_count': 2,
'max_leaf_depth': 2,
'max_node_value': 5,
Expand All @@ -557,6 +566,7 @@ def test_tree_properties():
assert root.is_min_heap is False
assert root.is_perfect is False
assert root.is_strict is False
assert root.is_symmetric is False
assert root.leaf_count == 2
assert root.max_leaf_depth == 2
assert root.max_node_value == 5
Expand All @@ -574,6 +584,7 @@ def test_tree_properties():
'is_min_heap': False,
'is_perfect': False,
'is_strict': False,
'is_symmetric': False,
'leaf_count': 2,
'max_leaf_depth': 3,
'max_node_value': 6,
Expand All @@ -589,6 +600,7 @@ def test_tree_properties():
assert root.is_min_heap is False
assert root.is_perfect is False
assert root.is_strict is False
assert root.is_symmetric is False
assert root.leaf_count == 2
assert root.max_leaf_depth == 3
assert root.max_node_value == 6
Expand All @@ -606,6 +618,7 @@ def test_tree_properties():
'is_min_heap': False,
'is_perfect': False,
'is_strict': False,
'is_symmetric': False,
'leaf_count': 2,
'max_leaf_depth': 3,
'max_node_value': 7,
Expand All @@ -621,6 +634,7 @@ def test_tree_properties():
assert root.is_min_heap is False
assert root.is_perfect is False
assert root.is_strict is False
assert root.is_symmetric is False
assert root.leaf_count == 2
assert root.max_leaf_depth == 3
assert root.max_node_value == 7
Expand Down Expand Up @@ -861,6 +875,7 @@ def test_heap_float_values():
assert root.is_min_heap == root_copy.is_min_heap
assert root.is_perfect == root_copy.is_perfect
assert root.is_strict == root_copy.is_strict
assert root.is_symmetric == root_copy.is_symmetric
assert root.leaf_count == root_copy.leaf_count
assert root.max_leaf_depth == root_copy.max_leaf_depth
assert root.max_node_value == root_copy.max_node_value + 0.1
Expand Down