Algorithms

Binary Side View

4 months, 2 weeks ago ; 75 views
Share this

Binary Side View

Let's solve the problem of obtaining the right side view of a binary tree.

To achieve that, here's a breakdown of how the pseudocode works:

  •     Initialize a deque q with the root node.
  •     Initialize an empty list res to store the right side view.
  •     While the deque q is not empty:
  •         For each level of the tree:
  •             Pop nodes from the left side of the deque.
  •             Keep track of the rightmost node encountered in the variable rightSide.
  •             If a node exists, add its left and right children to the deque.
  •         After processing all nodes in the current level, if rightSide exists, append its value to the result list res.
  •     Return the list res containing the values of nodes visible from the right side of the binary tree.

Code Implementation

import collections

class SolutionOne:
    def binary_Side_view(self, root):
        """
        Obtain the values of nodes visible from the right side of a binary tree.

        Args:
            root: The root node of the binary tree.

        Returns:
            list: A list containing the values of nodes visible from the right side of the binary tree.

        Example:
            # Create a binary tree
            #      1
            #     / \
            #    2   3
            #     \   \
            #      5   4
            root = TreeNode(1)
            root.left = TreeNode(2)
            root.right = TreeNode(3)
            root.left.right = TreeNode(5)
            root.right.right = TreeNode(4)

            # Instantiate the solution object
            solution = SolutionOne()

            # Obtain the values of nodes visible from the right side of the binary tree
            right_side_view = solution.binary_Side_view(root)

            print("Right side view of the binary tree:", right_side_view)
        """
        # Initialize a deque with the root node
        q = collections.deque([root])
        
        # Initialize an empty list to store the values of nodes visible from the right side
        res = []
        
        # While there are still nodes in the deque
        while q:
            # For each level of the tree
            for _ in range(len(q)):
                # Initialize a variable to keep track of the rightmost node at this level
                rightSide = None
                
                # Pop nodes from the left side of the deque
                node = q.popleft()
                
                # If the node exists
                if node:
                    # Update the rightmost node for this level
                    rightSide = node
                    
                    # Add the left child of the node to the deque if it exists
                    if node.left:
                        q.append(node.left)
                    
                    # Add the right child of the node to the deque if it exists
                    if node.right:
                        q.append(node.right)
                        
            # If there was a rightmost node at this level, append its value to the result list
            if rightSide:
                res.append(rightSide.val)
        
        # Return the list containing the values of nodes visible from the right side of the binary tree
        return res



The binary_Side_view function takes a binary tree root node as input and aims to return a list containing the values of nodes visible from the right side of the tree.

In other words, it's traversing the binary tree level by level, and for each level, it only keeps track of the rightmost node encountered. After traversing all levels, it returns the values of these rightmost nodes.

Time Complexity

The algorithm traverses each node of the binary tree once.

At each node, the algorithm performs constant time operations such as appending nodes to the deque and popping nodes from the deque.

Therefore, the time complexity of the algorithm is O(N), where N is the number of nodes in the binary tree.

Space Complexity

The algorithm utilizes a deque to perform level order traversal of the binary tree.

In the worst-case scenario, the deque may contain all nodes at a particular level of the binary tree.

Therefore, the space complexity of the algorithm is O(W), where W is the maximum width of the binary tree. In the worst case, the width of the binary tree can be N/2, where N is the total number of nodes in the binary tree. Hence, the space complexity can also be considered as O(N).

Unit Tests

We will use Python's built-in unittest module to write unit tests for the solution. Here's how you can structure the unit tests to test the correctness and robustness of the solution above:

import unittest

class TestSolutionOne(unittest.TestCase):
    def setUp(self):
        # Define a helper function to create a binary tree node
        class TreeNode:
            """TreeNode class Structure"""
            def __init__(self, val=0, left =None, right=None):
                self.val    = val
                self.left   = left
                self.right  = right
        
        # Create a sample binary tree
        #      1
        #     / \
        #    2   3
        #     \   \
        #      5   4
        self.tree = TreeNode(1)
        self.tree.left = TreeNode(2)
        self.tree.right = TreeNode(3)
        self.tree.left.right = TreeNode(5)
        self.tree.right.right = TreeNode(4)
        
        # Instantiate the solution object
        self.solution = SolutionOne()

    def test_correctness(self):
        # Expected right side view of the binary tree: [1, 3, 4]
        expected_right_side_view = [1, 3, 4]
        # Obtain the actual right side view using the solution
        actual_right_side_view = self.solution.binary_side_view(self.tree)
        # Assert that the actual result matches the expected result
        print(f"actual_right_side_view:: {actual_right_side_view}")
        self.assertEqual(actual_right_side_view, expected_right_side_view)

    def test_robustness(self):
        # Test with an empty binary tree
        empty_root = None
        # Expected right side view of the empty binary tree: []
        expected_empty_right_side_view = []
        # Obtain the actual right side view using the solution
        actual_empty_right_side_view = self.solution.binary_side_view(empty_root)
        # Assert that the actual result matches the expected result for the empty tree
        self.assertEqual(actual_empty_right_side_view, expected_empty_right_side_view)

if __name__ == '__main__':
    unittest.main()

In this test suite, we test test_correctness and  test_robustness.

The setUp is called before each test method, and it's used to set up any necessary objects or configurations for the tests.

The aim is to verify whether the solution produces the correct output for a sample binary tree and how it handles edge cases like an empty binary tree correctly.

Become a member
Get the latest news right in your inbox. We never spam!

Read next

Island Perimeter

 This solution seeks to find the perimeter of an island in a grid.  The problem considers a grid where each cell represents land (1) or … Read More

Kibsoft 3 months, 3 weeks ago . 76 views

Pacific Atlantic Waterflow

3 months, 3 weeks ago . 82 views