LeetCode刷题笔记 114(涉及到二叉树)

题目:二叉树展开为链表
给定一个二叉树,原地将它展开为链表。
例如,给定二叉树

    1
   / \
  2   5
 / \   \
3   4   6

将其展开为:

1
 \
  2
   \
    3
     \
      4
       \
        5
         \
          6

答案:

1.展开为链表的顺序其实就是二叉树的先序遍历。
(1)将原来的右子树接到左子树的最右边结点
(2)将左子树插入到右子树的地方
(3)根节点指向右子树的根节点,重复(1)(2)步骤,直至新的右子树为null

理解图示:

	    1
	   / \
	  2   5    
	 / \   \
	3   4   6
 //将1的右子树插入到左子树的最右边结点
	    1
	   / 
	  2       
	 / \   
	3   4   
	     \
	      5
	       \
	        6
  //将1的左子树插入到右子树的地方
        1
		 \
		  2       
		 / \   
		3   4   
		     \
		      5
		       \
		        6
  //将2的右子树插入到左子树的最右边结点
        1
		 \
		  2       
		 /    
		3   
		 \
		   4   
		    \
		      5
		       \
		        6
   //将2的左子树插入到右子树的地方
        1
		 \
		  2       
		   \  
			3   
			 \
			   4   
			    \
			      5
			       \
			        6
class Solution {
    public void flatten(TreeNode root) {
        while (root != null) { 
            //左子树为 null,直接考虑下一个节点
            if (root.left == null) {
                root = root.right;
            } else {
                // 找左子树最右边的节点
                TreeNode pre = root.left;
                while (pre.right != null) {
                    pre = pre.right;
                } 
                //将原来的右子树接到左子树的最右边节点
                pre.right = root.right;
                // 将左子树插入到右子树的地方
                root.right = root.left;
                root.left = null;
                // 考虑下一个节点
                root = root.right;
            }
        }
    }
}

2.类似先序遍历的非递归实现,将沿途的非空右子树根节点用栈保存起来,并将当前的左子树插入到右子树的地方(若左子树为空则将栈顶元素插入到右子树的地方)

	    11)遍历到1,将右子树5入栈,1的右子树指向2
	   / \           (2)遍历到2,将右子树4入栈,2的右子树指向3
	  2   53)遍历到3,因为右子树为空,所以无需入栈,3的右子树指向7
	 / \   \         (4)遍历到7,因为右子树为空,所以无需入栈,因为左子树为空,则弹出栈顶元素47的右子树指向4  
	3   4   65)遍历到4,将右子树9入栈,4的右子树指向8
   /   / \             ...
  7   8   9
class Solution {
    public void flatten(TreeNode root) {
        if(root == null) return;
        TreeNode p = root;
        Stack s = new Stack();
        while(p != null){    
            if(p.right != null)
                s.push(p.right);  //非空右子树根节点入栈
            if(p.left == null){   //左子树为空则将当前结点的右子树设为栈顶元素
                if(!s.isEmpty())
                    p.right = (TreeNode)s.pop();   
            }
            else p.right = p.left; //左子树不为空则将当前结点的右子树设为左子树
            p.left = null;
            p = p.right;           //遍历至当前结点的右子树
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值