I'm working on a recursive algorithm to flatten a binary tree into a singly linked list. Problem statement:
Given a binary tree, flatten it to a linked list in-place.
For example,
Given
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
I wrote the following recursive code that simply doesn't work (returns wrong answer), but I can't understand conceptually why not. Starting at the root, we flatten root.left and root.right. If root.left exists, then root.next (or in this case, root.right) will point to the flattened left list. Then, the left list points to the beginning of the right list. This continues recursively down the tree.
Is something wrong with this conceptually? I tried modeling it after a preorder traversal since essentially root is visited, then left, then right.
def flatten(root)
return root if root.nil?
left_list = flatten(root.left)
right_list = flatten(root.right)
root.left = nil
root.right = (left_list.nil? ? right_list : left_list)
find_tail(left_list).right = right_list unless left_list.nil?
end
def find_tail(node)
return nil if node.nil?
until node.right.nil?
node = node.right
end
node
end