Skip to content

Commit bf547fe

Browse files
committed
Handle nils in traversal
Skip nil children during postorder and breadth-first traversals so binary nodes with missing children do not break traversal. Add a regression test covering nil child traversal paths.
1 parent ddb7989 commit bf547fe

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

lib/tree.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ def postordered_each
679679
peek_node.visited = true
680680
# Add the children to the stack. Use the marking structure.
681681
marked_children =
682-
peek_node.node.children.map { |node| marked_node.new(node, false) }
682+
peek_node.node.children.compact.map { |node| marked_node.new(node, false) }
683683
node_stack = marked_children.concat(node_stack)
684684
next
685685
else
@@ -710,9 +710,11 @@ def breadth_each
710710
# Use a queue to do breadth traversal
711711
until node_queue.empty?
712712
node_to_traverse = node_queue.shift
713+
next unless node_to_traverse
714+
713715
yield node_to_traverse
714716
# Enqueue the children from left to right.
715-
node_to_traverse.children { |child| node_queue.push child }
717+
node_to_traverse.children { |child| node_queue.push child if child }
716718
end
717719

718720
self if block_given?

test/test_binarytree.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,5 +309,27 @@ def test_swap_children
309309
assert_equal(@right_child1, @root[0], 'right_child1 should now be the first child')
310310
assert_equal(@left_child1, @root[1], 'left_child1 should now be the last child')
311311
end
312+
313+
# Test traversals when nil children exist.
314+
def test_traversal_with_nil_children
315+
@root << @left_child1
316+
@root << @right_child1
317+
318+
@root.right_child = nil
319+
320+
breadth_nodes = []
321+
post_nodes = []
322+
323+
assert_nothing_raised do
324+
@root.breadth_each { |node| breadth_nodes << node }
325+
end
326+
327+
assert_nothing_raised do
328+
@root.postordered_each { |node| post_nodes << node }
329+
end
330+
331+
assert_equal([@root, @left_child1], breadth_nodes)
332+
assert_equal([@left_child1, @root], post_nodes)
333+
end
312334
end
313335
end

0 commit comments

Comments
 (0)