LeetCode Flatten Binary Tree to Linked List 将二叉树展开成链表

本文介绍三种方法将二叉树按前序遍历的方式展平为链表,利用右指针作为链表的下一个节点。通过递归及迭代方式详细解析每种方法的实现过程,并附带代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

Flatten a binary tree to a fake “linked list” in pre-order traversal.
Here we use the right pointer in TreeNode as the next pointer in ListNode.

样例输入:

     1
    / \
   2   5
  / \   \
 3   4   6

样例输出:

1
 \
  2
   \
    3
     \
      4
       \
        5
         \
          6

解法一
使用递归的思想,首先使用DFS思路找到左子树的最左节点,然后将该最左节点的父节点和右子树断开,把该最左节点连接到父节点的右节点上,左节点置为null,再把原右子树连接到原左子树的最右节点上,再往上遍历

步骤:
首先找到最左节点3

     1
    / \
   2   5
  / \   \
 3   4   6

断开父节点2和4的连接 把3连接到2的右子节点 再把4连接到3的右节点

     1
    / \
   2   5
    \   \
     3   6
      \
       4

再把1和右子树5断开 把左子树2连接到1的右节点上 右子树5连接到左子树的最右节点4的右节点上

1
 \
  2
   \
    3
     \
      4
       \
        5
         \
          6

代码

public void flattenRecursion(TreeNode root) {
    if (root == null) {
        return;
    }
    /*使用DFS思路找到最左子节点*/
    if (root.left != null) {
        flattenRecursion(root.left);
    }
    if (root.right != null) {
        flattenRecursion(root.right);
    }
    /*把其父节点和右子节点断开,将原左子结点连上父节点的右子节点上*/
    TreeNode tmp = root.right;
    root.right = root.left;
    root.left = null;
    /*然后再把原右子节点连到新右子节点的右子节点上*/
    while (root.right != null) {
        root = root.right;
    }
    root.right = tmp;
}

解法2
【递归能实现的循环就能实现┐(‘~`;)┌ 】首先判断当前节点的左子树是否为空,如果左子树非空的话,就断开当前节点和右子树,把当前节点的右指针指向左子树,再把原右子树连接到原左子树的最右节点
步骤描述:

     1
    / \
   2   5
  / \   \
 3   4   6

首先根节点1的左子树2非空 断开1和5的连接 把1的右指针指向2 再把右子树5连接到2的最右节点4的右节点上

     1
      \
       2
      / \
     3   4
          \
           5
            \
             6

再继续判断以2为根的树 2的左节点3非空 继续进行上述操作

1
 \
  2
   \
    3
     \
      4
       \
        5
         \
          6

代码实现

public void flattenLoop(TreeNode root) {
   public void flattenLoop(TreeNode root) {
    TreeNode cur = root;
    while (cur != null) {
        //遍历节点 如果左节点不为空的话
        if (cur.left != null) {
            //找到左子树的最右节点 目的是把原右子树连接到该节点的右节点上
            TreeNode p = cur.left;
            while (p.right != null) {
                p = p.right;
            }
            //断开当前节点和右子树 把左子树连接到当前节点的右节点 把原右子树连接到原左子树的最右节点的右子树上
            p.right = cur.right;
            cur.right = cur.left;
            cur.left = null;
        }
        //当前节点为右子树的根节点 即原左子树的根节点
        cur = cur.right;
    }
}

解法三
使用层序遍历来实现 需要借助辅助空间来实现

 public void flattenPreOrder(TreeNode root) {
    if(root == null){
         return;
     }
     Stack<TreeNode> stack = new Stack<TreeNode>();
     stack.push(root);
     while(!stack.empty()){
         TreeNode tmp = stack.pop();
         if(tmp.left!=null){
             TreeNode l = tmp.left;
             while(l.right!=null){
                 l = l.right;
             }
             TreeNode r = tmp.right;
             tmp.right = tmp.left;
             tmp.left = null;
             l.right = r;
         }
         if(tmp.right!=null){
             stack.push(tmp.right);
         }
     }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值