Problem Challenge 2
Problem statement
Given a binary tree, return an array containing nodes in its right view. The right view of a binary tree is the set of nodes visible when the tree is seen from the right side.
Dry-run templates
The following is the implementation of the solution provided for the problem posed in the Problem Challenge 2 lesson.
from __future__ import print_functionfrom collections import dequeclass TreeNode:def __init__(self, val):self.val = valself.left, self.right = None, Nonedef tree_right_view(root):result = []if root is None:return resultqueue = deque()queue.append(root)while queue:levelSize = len(queue)for i in range(0, levelSize):currentNode = queue.popleft()# if it is the last node of this level, add it to the resultif i == levelSize - 1:result.append(currentNode)# insert the children of current node in the queueif currentNode.left:queue.append(currentNode.left)if currentNode.right:queue.append(currentNode.right)return resultdef main():root = TreeNode(12)root.left = TreeNode(7)root.right = TreeNode(1)root.left.left = TreeNode(9)root.right.left = TreeNode(10)root.right.right = TreeNode(5)root.left.left.left = TreeNode(3)result = tree_right_view(root)print("Tree right view: ")for node in result:print(str(node.val) + " ", end='')main()
Sample input #1
root = TreeNode(12)
root.left = TreeNode(7)
root.right = TreeNode(1)
root.left.left = TreeNode(9)
root.right.left = TreeNode(10)
root.right.right = TreeNode(5)
root.left.left.left = TreeNode(3)
_ 12 _
| |
_ 7 __ 1 _
| | |
_ 9 10 5
|
3
Line number | While loop iteration | For loop iteration | levelSize | currentNode | queue | result | Nodes in right view |
12-17 | - | - | - | - | [12] | [ ] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
18-19 | 1 | - | 1 | - | [12] | [ ] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 1 | 1 | 1 | 12 | [7, 1] | [12] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
18-19 | 2 | - | 2 | - | [7, 1] | [12] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 2 | 1 | 2 | 7 | [1, 9] | [12] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 2 | 2 | 2 | 1 | [9, 10, 5] | [12, 1] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
18-19 | 3 | - | 3 | - | [9, 10, 5] | [12, 1] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 3 | 1 | 3 | 9 | [10, 5, 3] | [12, 1] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 3 | 2 | 3 | 10 | [5, 3] | [12, 1] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 3 | 3 | 3 | 5 | [3] | [12, 1, 5] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
18-19 | 4 | - | 1 | - | [3] | [12, 1, 5] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
20-29 | 4 | 1 | 1 | 3 | [ ] | [12, 1, 5, 3] | _ 12 _ | | _ 7 __ 1 _ | | | _ 9 10 5 | 3 |
Sample input #2
root = TreeNode(14)
root.left = TreeNode(7)
root.right = TreeNode(1)
root.right.left = TreeNode(10)
root.right.right = TreeNode(5)
_ 14 _
| |
7 __ 1 _
| |
10 5
Students may be encouraged to complete the following dry-run table themselves.
Line number | While loop iteration | For loop iteration | levelSize | currentNode | queue | result | Nodes in right view |
12-17 | - | - | - | - | [14] | [ ] | _ 14 _ | | 7 __ 1 _ | | 10 5 |
18-19 | 1 | - | 1 | - | [14] | [ ] | _ 14 _ | | 7 __ 1 _ | | 10 5 |
20-29 | 1 | 1 | 1 | 14 | [7, 1] | [14] | _ 14 _ | | 7 __ 1 _ | | 10 5 |
... | ... | ... | ... | ... | ... | ... | ... |
Trace generation
The output of the following code shows the traces generated via print
statements.
Note:
draw_node
anddisplay_tree
methods aid in visualizing the tree structure. The students can be encouraged to write these methods themselves. They don’t affect the code execution.
printq()
is used to print node values inqueue
andresult
.
from __future__ import print_functionfrom collections import dequeimport copy# Display List Code Below:def height(node):if (node == None):return 0return 1 + max(height(node.left), height(node.right))def draw_node(output, link_above, node, level, p, link_char):if (node == None):returnout = "["h = len(output)SP = " "if (p < 0):for s in output:if (s):s = " "*(-1*p) + sfor s in link_above:if (s):s = " "*(-1*p) + sif level < h - 1:p = max(p, len(output[level + 1]))if (level > 0):p = max(p, len(output[level - 1]))p = max(p, len(output[level]))# Fill in to leftif (node.left):leftData = SP + str(node.left.val) + SPdraw_node(output, link_above, node.left, level + 1, p - len(leftData),'L')p = max(p, len(output[level + 1]))# Enter this dataspace = p - len(output[level])if (space > 0):output[level] += (' ' * space)node_data = SP + str(node.val) + SPoutput[level] += node_data# Add vertical link abovespace = p + len(SP) - len(link_above[level])if (space > 0):link_above[level] += (' ' * space)link_above[level] += link_char# Fill in to rightif (node.right):draw_node(output, link_above, node.right, level + 1, len(output[level]),'R')def display_tree(root):if (root == None):print("\tNone")h = height(root)output = []link_above = []for i in range(0,h):output.append("")link_above.append("")draw_node(output, link_above, root, 0, 5, ' ')# Create link linesfor i in range(h):for j in range(len(link_above[i])):if (link_above[i][j] != ' '):size = len(output[i - 1])if (size < j + 1):output[i - 1] += " " *(j + 1 - size)jj = jif (link_above[i][j] == 'L'):while (output[i - 1][jj] == ' '):jj += 1for k in range(j+1, jj-1):str1 = output[i - 1]list1 = list(str1)list1[k] = '_'output[i - 1] = ''.join(list1)elif(link_above[i][j] == 'R'):while (output[i - 1][jj] == ' '):jj-=1# k = j-1for k in range(j-1,jj+1,-1):temp = output[i - 1]list1 = list(temp)list1[k] = '_'output[i - 1] = ''.join(list1)k = k - 1str1 = link_above[i]list1 = list(str1)list1[j] = '|'link_above[i] = ''.join(list1)# Outputfor i in range(h):if (i):print("\t" , link_above[i])print("\t" , output[i])def printq(queue):strqueue = "["for i in queue:strqueue += str(i.val) + ", "if not queue:str2 = strqueue+"]"return str2str2 = strqueue[:-2]+"]"return str2class TreeNode:def __init__(self, val):self.val = valself.left, self.right = None, Nonedef traversal(root, result):if root is None:returnif root in result:root.val = str(root.val) + "*"traversal(root.left, result)traversal(root.right, result)def tree_right_view(root):result = []if root is None:return resultprint("Result: ", printq(result), sep = "")queue = deque()queue.append(root)print("Appending root to queue: ", printq(queue), sep = "")print("")j = 1while queue:print("While loop iteration: ", j, sep = "")j+=1levelSize = len(queue)print("\tLength of queue --> levelSize: ", levelSize, sep = "")l = 1for i in range(0, levelSize):print("\t\tFor loop iteration: ", l, sep = "")l +=1tempqueue = deque()tempqueue = copy.copy(queue)currentNode = queue.popleft()print("\t\t\tPopping from the queue: ", printq(tempqueue), " --> ", printq(queue), sep = "")print("\t\t\tcurrentNode: ", currentNode.val,sep="" )# if it is the last node of this level, add it to the resultif i == levelSize - 1:result.append(currentNode)print("\t\t\t", currentNode.val, " is the last node of level ", levelSize, " --> appending to result", sep = "")print("\t\t\tResult: ", printq(result), sep = "")# insert the children of current node in the queueif currentNode.left or currentNode.right:print("\t\t\tInserting children of the current node, ", currentNode.val,", in the queue", sep = "")else:print("\t\t\tCurrent node, ", currentNode.val, ", does not have any children", sep = "")if currentNode.left:queue.append(currentNode.left)print("\t\t\t\tAppending left child: ", printq(queue), sep = "")if currentNode.right:queue.append(currentNode.right)print("\t\t\t\tAppending right child: ", printq(queue),"\n", sep = "")return resultdef main():root = TreeNode(12)root.left = TreeNode(7)root.right = TreeNode(1)root.left.left = TreeNode(9)root.right.left = TreeNode(10)root.right.right = TreeNode(5)root.left.left.left = TreeNode(3)root2 = TreeNode(14)root2.left = TreeNode(7)root2.right = TreeNode(1)root2.right.left = TreeNode(10)root2.right.right = TreeNode(5)input = [root, root2]for i in input:print("Input tree: ")display_tree(i)print("")result = tree_right_view(i)print("Tree right view: ")str_out = ""for node in result:str_out += str(node.val) + ", "str_out = "[" + str_out[:-2] + "]"print(str_out)traversal(i, result)print("")display_tree(i)print(("-"*100)+"\n")main()
An asterisk (*) next to a node indicates that it has been included in the right view.