题目描述:
给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
1
/
2 5
/
3 4 6
将其展开为:
1 2 3 4 5 6
解法一
我们需要两步完成这道题。
- 将左子树插入到右子树的地方
- 将原来的右子树接到左子树的最右边节点
考虑新的右子树的根节点,一直重复上边的过程,直到新的右子树为 null
过程如下展示
1 / 2 5 / 3 4 6 //将 1 的左子树插入到右子树的地方 1 2 5 / 3 4 6 //将原来的右子树接到左子树的最右边节点 1 2 / 3 4 5 6 //将 2 的左子树插入到右子树的地方 1 2 3 4 5 6 //将原来的右子树接到左子树的最右边节点 1 2 3 4 5 6
//go func flatten(root *TreeNode) { for root != nil { if root.Left == nil { root = root.Right }else { pre := root.Left for pre.Right != nil { pre = pre.Right } pre.Right = root.Right root.Right = root.Left root.Left = nil root = root.Right } } }
方法二
先序遍历为1-2-3-4-5-6,如果按照先序遍历执行,1的左孩子为nil,右孩子为2,但是5就没了。所以不能直接使用先序遍历。
但是我们可以逆先序遍历:6-5-4-3-2-1
然后每遍历一个节点就将当前节点的右指针更新为上一个节点。
遍历到 5,把 5 的右指针指向 6。6 <- 5 4 3 2 1。
遍历到 4,把 4 的右指针指向 5。6 <- 5 <- 4 3 2 1。
……
(这个思想打个比方就像接链条,我们先把尾部的接好,在往头部拼接,整体就串起来了)
//go func flatten(root *TreeNode) { if root==nil{ return } var pre *TreeNode //使用2重指针 dfs(root,pre) } func dfs(root *TreeNode,pre *TreeNode){ if root==nil{ return } dfs(root.Right,pre) dfs(root.Left,pre) root.Right= pre root.Left=nil pre =root }