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
Solution 1:
Pre-order前序遍历。用一个prev节点保存上次访问的节点,然后更新其左孩子和右孩子。
private TreeNode prev = null; public void flatten(TreeNode root) { if(root == null) return; TreeNode right = root.right; //必需保存起来,要不然就在flatten左子节点时被更新了 if(prev != null) { prev.left = null; //因为更新左子节点的时候,左子节点已经拿到,故不用特殊保存 prev.right = root; //因为前序遍历,右子节点最后访问,此时右子节点已保存,可更新 } prev = root; flatten(root.left); flatten(right); //注意,这个地方不能是root.right,要不然会StackOverFlow }
Solution 2:
非递归的做法。
public void flatten(TreeNode root) { TreeNode node = root; while(node != null) { if(node.left != null) { TreeNode rightLeaf = node.left; while(rightLeaf.right != null) { rightLeaf = rightLeaf.right; } rightLeaf.right = node.right; node.right = node.left; node.left = null; } node = node.right; } }
Solution 3:
非递归用栈来处理。
public void flatten(TreeNode root) { if(root == null) return; Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); TreeNode leaf = root; while(!stack.isEmpty()) { TreeNode node = stack.pop(); if(node.right != null) stack.push(node.right); if(node.left != null) stack.push(node.left); if(leaf != node) { leaf.left = null; leaf.right = node; leaf = node; } } }