二叉树展开为链表
题目描述:
给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
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
}
small_lei_it 技术无止境,追求更高。

浙公网安备 33010602011771号