二叉树展开为链表

题目描述:

给定一个二叉树,原地将它展开为一个单链表。

例如,给定二叉树

    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
}

  地址:https://mp.weixin.qq.com/s/4PNuVEgXJpCWgzVl35eQ2g

原文地址:https://www.cnblogs.com/smallleiit/p/13450748.html