From ddefa045bb46f8a77053580390562903a8c75820 Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 02:06:40 +0530 Subject: [PATCH 01/12] Add `Invert a Binary Tree` solution --- .../binary_tree/invert_binary_tree.py | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 data_structures/binary_tree/invert_binary_tree.py diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py new file mode 100644 index 000000000000..0c0f6057efad --- /dev/null +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -0,0 +1,76 @@ +""" +Given the root of a binary tree, invert the tree, and return its root. + +Leetcode problem reference: https://leetcode.com/problems/invert-binary-tree/ +""" + +from __future__ import annotations + + +class Node: + """ + A Node has value variable and pointers to Nodes to its left and right. + """ + + def __init__(self, value: int) -> None: + self.value = value + self.left: Node | None = None + self.right: Node | None = None + + +def display(tree: Node | None) -> None: + """ + Prints the inorder traversal of a tree + """ + if tree: + display(tree.left) + print(tree.value, end=" ") + display(tree.right) + +def invert_binary_tree(root: Node| None) -> None: + """ + Inverts a binary tree and returns the root node of the binary tree + """ + if root != None: #If root is not None + temp = root.left #Save left Node in a temp variable + # Swap the Nodes + root.left = root.right + root.right = temp + # Now, invoke the function recursively for both the children + invert_binary_tree(root.left) + invert_binary_tree(root.right) + # Return the Node + return root + +if __name__ == "__main__": + # Create a binary tree with 7 Nodes + t1 = Node(1) + t1.left = Node(2) + t1.right = Node(3) + t1.left.left = Node(4) + t1.left.right = Node(5) + t1.right.left = Node(6) + t1.right.right = Node(7) + + """ + The tree is like + 1 + 2 3 + 4 5 6 7 + """ + + print("Tree: ",end=" ") + display(t1) + + #Invert the binary tree (t1) and store the returned Node in t2 + t2 = invert_binary_tree(t1) + """ + The inverted tree is like + 1 + 3 2 + 7 6 5 4 + """ + + print("\nInverted Tree: ", end=" ") + display(t2) + print() \ No newline at end of file From a6fdd44c42485f58f22e93444bb4c9263c6c974f Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 02:20:02 +0530 Subject: [PATCH 02/12] Add type --- data_structures/binary_tree/invert_binary_tree.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 0c0f6057efad..d5352831d8c5 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -32,7 +32,7 @@ def invert_binary_tree(root: Node| None) -> None: Inverts a binary tree and returns the root node of the binary tree """ if root != None: #If root is not None - temp = root.left #Save left Node in a temp variable + temp : Node = root.left #Save left Node in a temp variable # Swap the Nodes root.left = root.right root.right = temp @@ -44,7 +44,7 @@ def invert_binary_tree(root: Node| None) -> None: if __name__ == "__main__": # Create a binary tree with 7 Nodes - t1 = Node(1) + t1 : Node = Node(1) t1.left = Node(2) t1.right = Node(3) t1.left.left = Node(4) @@ -63,7 +63,7 @@ def invert_binary_tree(root: Node| None) -> None: display(t1) #Invert the binary tree (t1) and store the returned Node in t2 - t2 = invert_binary_tree(t1) + t2 : Node = invert_binary_tree(t1) """ The inverted tree is like 1 From 7b9dc8a07ee815a920ddd32ac69832e78cc1aa03 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 20:51:10 +0000 Subject: [PATCH 03/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../binary_tree/invert_binary_tree.py | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index d5352831d8c5..40db3d7f3b61 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -18,7 +18,7 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def display(tree: Node | None) -> None: +def display(tree: Node | None) -> None: """ Prints the inorder traversal of a tree """ @@ -27,24 +27,26 @@ def display(tree: Node | None) -> None: print(tree.value, end=" ") display(tree.right) -def invert_binary_tree(root: Node| None) -> None: + +def invert_binary_tree(root: Node | None) -> None: """ Inverts a binary tree and returns the root node of the binary tree """ - if root != None: #If root is not None - temp : Node = root.left #Save left Node in a temp variable - # Swap the Nodes - root.left = root.right - root.right = temp - # Now, invoke the function recursively for both the children - invert_binary_tree(root.left) - invert_binary_tree(root.right) + if root != None: # If root is not None + temp: Node = root.left # Save left Node in a temp variable + # Swap the Nodes + root.left = root.right + root.right = temp + # Now, invoke the function recursively for both the children + invert_binary_tree(root.left) + invert_binary_tree(root.right) # Return the Node return root + if __name__ == "__main__": # Create a binary tree with 7 Nodes - t1 : Node = Node(1) + t1: Node = Node(1) t1.left = Node(2) t1.right = Node(3) t1.left.left = Node(4) @@ -59,18 +61,18 @@ def invert_binary_tree(root: Node| None) -> None: 4 5 6 7 """ - print("Tree: ",end=" ") - display(t1) + print("Tree: ", end=" ") + display(t1) - #Invert the binary tree (t1) and store the returned Node in t2 - t2 : Node = invert_binary_tree(t1) + # Invert the binary tree (t1) and store the returned Node in t2 + t2: Node = invert_binary_tree(t1) """ The inverted tree is like 1 3 2 - 7 6 5 4 + 7 6 5 4 """ print("\nInverted Tree: ", end=" ") - display(t2) - print() \ No newline at end of file + display(t2) + print() From 8585e6769972e97a36d66e7c45c919adba75b1ce Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 02:52:18 +0530 Subject: [PATCH 04/12] Add `doctest` --- .../binary_tree/invert_binary_tree.py | 103 ++++++++++-------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 40db3d7f3b61..97fc2eea5ef5 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -5,6 +5,7 @@ """ from __future__ import annotations +from typing import Optional class Node: @@ -18,61 +19,73 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def display(tree: Node | None) -> None: +def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: """ Prints the inorder traversal of a tree """ + if tree_list is None: + tree_list = [] + if tree: - display(tree.left) - print(tree.value, end=" ") - display(tree.right) + get_tree_inorder(tree.left, tree_list) + tree_list.append(tree.value) + get_tree_inorder(tree.right, tree_list) + return tree_list -def invert_binary_tree(root: Node | None) -> None: - """ - Inverts a binary tree and returns the root node of the binary tree - """ - if root != None: # If root is not None - temp: Node = root.left # Save left Node in a temp variable - # Swap the Nodes - root.left = root.right - root.right = temp - # Now, invoke the function recursively for both the children - invert_binary_tree(root.left) - invert_binary_tree(root.right) - # Return the Node - return root +def invert_binary_tree(root: Optional[Node]) -> None: + r""" + The tree looks like this + 1 + / \ + 2 3 + / \ \ + 4 5 6 + / \ \ + 7 8 9 -if __name__ == "__main__": - # Create a binary tree with 7 Nodes - t1: Node = Node(1) - t1.left = Node(2) - t1.right = Node(3) - t1.left.left = Node(4) - t1.left.right = Node(5) - t1.right.left = Node(6) - t1.right.right = Node(7) - """ - The tree is like - 1 - 2 3 - 4 5 6 7 - """ + >>> tree = Node(1) + >>> tree.left = Node(2) + >>> tree.right = Node(3) + >>> tree.left.left = Node(4) + >>> tree.left.right = Node(5) + >>> tree.right.right = Node(6) + >>> tree.left.left.left = Node(7) + >>> tree.left.left.right = Node(8) + >>> tree.left.right.right = Node(9) - print("Tree: ", end=" ") - display(t1) + >>> get_tree_inorder(tree) + [7, 4, 8, 2, 5, 9, 1, 3, 6] + >>> inverted_tree = invert_binary_tree(tree) + >>> get_tree_inorder(inverted_tree) + [6, 3, 1, 9, 5, 2, 8, 4, 7] - # Invert the binary tree (t1) and store the returned Node in t2 - t2: Node = invert_binary_tree(t1) - """ - The inverted tree is like - 1 - 3 2 - 7 6 5 4 + The inverted tree looks like this + 1 + / \ + 3 2 + / / \ + 6 5 4 + / / \ + 9 8 7 """ - print("\nInverted Tree: ", end=" ") - display(t2) - print() + + if root != None: #If root is not None + temp : Node = root.left #Save left Node in a temp variable + # Swap the Nodes + root.left = root.right + root.right = temp + # Now, invoke the function recursively for both the children + invert_binary_tree(root.left) + invert_binary_tree(root.right) + # Return the Node + return root + + +if __name__ == "__main__": + + import doctest + doctest.testmod() \ No newline at end of file From 105badb7be17aca7428c39d7e75b452430e3bc4a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 21:22:52 +0000 Subject: [PATCH 05/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../binary_tree/invert_binary_tree.py | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 97fc2eea5ef5..44453f2654d9 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -19,7 +19,7 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: +def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: """ Prints the inorder traversal of a tree """ @@ -33,8 +33,8 @@ def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: return tree_list -def invert_binary_tree(root: Optional[Node]) -> None: +def invert_binary_tree(root: Optional[Node]) -> None: r""" The tree looks like this 1 @@ -66,26 +66,25 @@ def invert_binary_tree(root: Optional[Node]) -> None: 1 / \ 3 2 - / / \ - 6 5 4 - / / \ - 9 8 7 + / / \ + 6 5 4 + / / \ + 9 8 7 """ - - if root != None: #If root is not None - temp : Node = root.left #Save left Node in a temp variable - # Swap the Nodes - root.left = root.right - root.right = temp - # Now, invoke the function recursively for both the children - invert_binary_tree(root.left) - invert_binary_tree(root.right) + if root != None: # If root is not None + temp: Node = root.left # Save left Node in a temp variable + # Swap the Nodes + root.left = root.right + root.right = temp + # Now, invoke the function recursively for both the children + invert_binary_tree(root.left) + invert_binary_tree(root.right) # Return the Node return root if __name__ == "__main__": - import doctest - doctest.testmod() \ No newline at end of file + + doctest.testmod() From 5ff2763201a8d532cca89827f8a47309942be2a6 Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 02:56:54 +0530 Subject: [PATCH 06/12] Add `test` to `get_tree_inorder` --- data_structures/binary_tree/invert_binary_tree.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 44453f2654d9..f8bcaa507b83 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -19,9 +19,19 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: - """ +def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: + r""" Prints the inorder traversal of a tree + + >>> tree = Node(1) + >>> tree.left = Node(2) + >>> tree.right = Node(3) + >>> tree.left.left = Node(4) + >>> tree.left.right = Node(5) + >>> tree.right.left = Node(6) + >>> tree.right.right = Node(7) + >>> get_tree_inorder(tree) + [4, 2, 5, 1, 6, 3, 7] """ if tree_list is None: tree_list = [] From 758a7f914df2d536e6e79fb0c8baa0700dfe903f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 21:27:29 +0000 Subject: [PATCH 07/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/binary_tree/invert_binary_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index f8bcaa507b83..ce329c5acefc 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -19,7 +19,7 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: +def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: r""" Prints the inorder traversal of a tree From 94f0aed394ebe84ef9b68f077a373b389c89eab7 Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 03:08:45 +0530 Subject: [PATCH 08/12] Add `test` changes --- data_structures/binary_tree/invert_binary_tree.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index ce329c5acefc..3e6d5fe4a384 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -5,7 +5,6 @@ """ from __future__ import annotations -from typing import Optional class Node: @@ -19,7 +18,7 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: +def get_tree_inorder(tree: Node | None, tree_list: list | None) -> list: r""" Prints the inorder traversal of a tree @@ -30,7 +29,7 @@ def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: >>> tree.left.right = Node(5) >>> tree.right.left = Node(6) >>> tree.right.right = Node(7) - >>> get_tree_inorder(tree) + >>> get_tree_inorder(tree,[]) [4, 2, 5, 1, 6, 3, 7] """ if tree_list is None: @@ -44,8 +43,10 @@ def get_tree_inorder(tree: Optional[Node], tree_list: list = None) -> list: return tree_list -def invert_binary_tree(root: Optional[Node]) -> None: +def invert_binary_tree(root: Node | None) -> None: r""" + Inverts the binary tree with the given root and returns the root + The tree looks like this 1 / \ @@ -66,10 +67,10 @@ def invert_binary_tree(root: Optional[Node]) -> None: >>> tree.left.left.right = Node(8) >>> tree.left.right.right = Node(9) - >>> get_tree_inorder(tree) + >>> get_tree_inorder(tree,[]) [7, 4, 8, 2, 5, 9, 1, 3, 6] >>> inverted_tree = invert_binary_tree(tree) - >>> get_tree_inorder(inverted_tree) + >>> get_tree_inorder(inverted_tree,[]) [6, 3, 1, 9, 5, 2, 8, 4, 7] The inverted tree looks like this From 4db2efdbd6d8645a487736b47ad2d1fbc93430e1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 21:41:26 +0000 Subject: [PATCH 09/12] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- data_structures/binary_tree/invert_binary_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 3e6d5fe4a384..56aca879eafb 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -18,7 +18,7 @@ def __init__(self, value: int) -> None: self.right: Node | None = None -def get_tree_inorder(tree: Node | None, tree_list: list | None) -> list: +def get_tree_inorder(tree: Node | None, tree_list: list | None) -> list: r""" Prints the inorder traversal of a tree From bdd6cb59c582c232f88e5e54fe0d479470cfa81c Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 03:14:03 +0530 Subject: [PATCH 10/12] Fix lint errors --- data_structures/binary_tree/invert_binary_tree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 56aca879eafb..5b71c951c51b 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -83,7 +83,7 @@ def invert_binary_tree(root: Node | None) -> None: 9 8 7 """ - if root != None: # If root is not None + if root is not None: # If root is not None temp: Node = root.left # Save left Node in a temp variable # Swap the Nodes root.left = root.right From 8c8c31910d1509aa537112a4d8c604b22a0fd61f Mon Sep 17 00:00:00 2001 From: gouravrajbit Date: Tue, 3 Oct 2023 03:19:50 +0530 Subject: [PATCH 11/12] Fix precommit errors --- data_structures/binary_tree/invert_binary_tree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py index 5b71c951c51b..147d58b64a56 100644 --- a/data_structures/binary_tree/invert_binary_tree.py +++ b/data_structures/binary_tree/invert_binary_tree.py @@ -43,7 +43,7 @@ def get_tree_inorder(tree: Node | None, tree_list: list | None) -> list: return tree_list -def invert_binary_tree(root: Node | None) -> None: +def invert_binary_tree(root: Node | None) -> Node | None: r""" Inverts the binary tree with the given root and returns the root @@ -84,7 +84,7 @@ def invert_binary_tree(root: Node | None) -> None: """ if root is not None: # If root is not None - temp: Node = root.left # Save left Node in a temp variable + temp: Node | None = root.left # Save left Node in a temp variable # Swap the Nodes root.left = root.right root.right = temp From 67e780d19c94d7184b32c835ab30c7a6c648cf96 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 24 Oct 2023 09:43:46 +0200 Subject: [PATCH 12/12] Update and rename invert_binary_tree.py to mirror_binary_tree.py --- .../binary_tree/invert_binary_tree.py | 101 ------------ .../binary_tree/mirror_binary_tree.py | 153 ++++++++++++++++++ 2 files changed, 153 insertions(+), 101 deletions(-) delete mode 100644 data_structures/binary_tree/invert_binary_tree.py create mode 100644 data_structures/binary_tree/mirror_binary_tree.py diff --git a/data_structures/binary_tree/invert_binary_tree.py b/data_structures/binary_tree/invert_binary_tree.py deleted file mode 100644 index 147d58b64a56..000000000000 --- a/data_structures/binary_tree/invert_binary_tree.py +++ /dev/null @@ -1,101 +0,0 @@ -""" -Given the root of a binary tree, invert the tree, and return its root. - -Leetcode problem reference: https://leetcode.com/problems/invert-binary-tree/ -""" - -from __future__ import annotations - - -class Node: - """ - A Node has value variable and pointers to Nodes to its left and right. - """ - - def __init__(self, value: int) -> None: - self.value = value - self.left: Node | None = None - self.right: Node | None = None - - -def get_tree_inorder(tree: Node | None, tree_list: list | None) -> list: - r""" - Prints the inorder traversal of a tree - - >>> tree = Node(1) - >>> tree.left = Node(2) - >>> tree.right = Node(3) - >>> tree.left.left = Node(4) - >>> tree.left.right = Node(5) - >>> tree.right.left = Node(6) - >>> tree.right.right = Node(7) - >>> get_tree_inorder(tree,[]) - [4, 2, 5, 1, 6, 3, 7] - """ - if tree_list is None: - tree_list = [] - - if tree: - get_tree_inorder(tree.left, tree_list) - tree_list.append(tree.value) - get_tree_inorder(tree.right, tree_list) - - return tree_list - - -def invert_binary_tree(root: Node | None) -> Node | None: - r""" - Inverts the binary tree with the given root and returns the root - - The tree looks like this - 1 - / \ - 2 3 - / \ \ - 4 5 6 - / \ \ - 7 8 9 - - - >>> tree = Node(1) - >>> tree.left = Node(2) - >>> tree.right = Node(3) - >>> tree.left.left = Node(4) - >>> tree.left.right = Node(5) - >>> tree.right.right = Node(6) - >>> tree.left.left.left = Node(7) - >>> tree.left.left.right = Node(8) - >>> tree.left.right.right = Node(9) - - >>> get_tree_inorder(tree,[]) - [7, 4, 8, 2, 5, 9, 1, 3, 6] - >>> inverted_tree = invert_binary_tree(tree) - >>> get_tree_inorder(inverted_tree,[]) - [6, 3, 1, 9, 5, 2, 8, 4, 7] - - The inverted tree looks like this - 1 - / \ - 3 2 - / / \ - 6 5 4 - / / \ - 9 8 7 - """ - - if root is not None: # If root is not None - temp: Node | None = root.left # Save left Node in a temp variable - # Swap the Nodes - root.left = root.right - root.right = temp - # Now, invoke the function recursively for both the children - invert_binary_tree(root.left) - invert_binary_tree(root.right) - # Return the Node - return root - - -if __name__ == "__main__": - import doctest - - doctest.testmod() diff --git a/data_structures/binary_tree/mirror_binary_tree.py b/data_structures/binary_tree/mirror_binary_tree.py new file mode 100644 index 000000000000..39305c2a9da2 --- /dev/null +++ b/data_structures/binary_tree/mirror_binary_tree.py @@ -0,0 +1,153 @@ +""" +Given the root of a binary tree, mirror the tree, and return its root. + +Leetcode problem reference: https://leetcode.com/problems/mirror-binary-tree/ +""" +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass + + +@dataclass +class Node: + """ + A Node has value variable and pointers to Nodes to its left and right. + """ + + value: int + left: Node | None = None + right: Node | None = None + + def __iter__(self) -> Iterator[int]: + if self.left: + yield from self.left + yield self.value + if self.right: + yield from self.right + + def __len__(self) -> int: + return sum(1 for _ in self) + + def mirror(self) -> Node: + """ + Mirror the binary tree rooted at this node by swapping left and right children. + + >>> tree = Node(0) + >>> list(tree) + [0] + >>> list(tree.mirror()) + [0] + >>> tree = Node(1, Node(0), Node(3, Node(2), Node(4, None, Node(5)))) + >>> tuple(tree) + (0, 1, 2, 3, 4, 5) + >>> tuple(tree.mirror()) + (5, 4, 3, 2, 1, 0) + """ + self.left, self.right = self.right, self.left + if self.left: + self.left.mirror() + if self.right: + self.right.mirror() + return self + + +def make_tree_seven() -> Node: + r""" + Return a binary tree with 7 nodes that looks like this: + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 + + >>> tree_seven = make_tree_seven() + >>> len(tree_seven) + 7 + >>> list(tree_seven) + [4, 2, 5, 1, 6, 3, 7] + """ + tree = Node(1) + tree.left = Node(2) + tree.right = Node(3) + tree.left.left = Node(4) + tree.left.right = Node(5) + tree.right.left = Node(6) + tree.right.right = Node(7) + return tree + + +def make_tree_nine() -> Node: + r""" + Return a binary tree with 9 nodes that looks like this: + 1 + / \ + 2 3 + / \ \ + 4 5 6 + / \ \ + 7 8 9 + + >>> tree_nine = make_tree_nine() + >>> len(tree_nine) + 9 + >>> list(tree_nine) + [7, 4, 8, 2, 5, 9, 1, 3, 6] + """ + tree = Node(1) + tree.left = Node(2) + tree.right = Node(3) + tree.left.left = Node(4) + tree.left.right = Node(5) + tree.right.right = Node(6) + tree.left.left.left = Node(7) + tree.left.left.right = Node(8) + tree.left.right.right = Node(9) + return tree + + +def main() -> None: + r""" + Mirror binary trees with the given root and returns the root + + >>> tree = make_tree_nine() + >>> tuple(tree) + (7, 4, 8, 2, 5, 9, 1, 3, 6) + >>> tuple(tree.mirror()) + (6, 3, 1, 9, 5, 2, 8, 4, 7) + + nine_tree: + 1 + / \ + 2 3 + / \ \ + 4 5 6 + / \ \ + 7 8 9 + + The mirrored tree looks like this: + 1 + / \ + 3 2 + / / \ + 6 5 4 + / / \ + 9 8 7 + """ + trees = {"zero": Node(0), "seven": make_tree_seven(), "nine": make_tree_nine()} + for name, tree in trees.items(): + print(f" The {name} tree: {tuple(tree)}") + # (0,) + # (4, 2, 5, 1, 6, 3, 7) + # (7, 4, 8, 2, 5, 9, 1, 3, 6) + print(f"Mirror of {name} tree: {tuple(tree.mirror())}") + # (0,) + # (7, 3, 6, 1, 5, 2, 4) + # (6, 3, 1, 9, 5, 2, 8, 4, 7) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + main()