【LeetCode】114. 二叉树展开为链表

本文介绍了一种将二叉树原地展平为单链表的方法,通过递归处理左、右子树并将左子树的最后一个节点指向右子树,实现树结构的链表化。代码示例使用C++实现。

1.题目

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

例如,给定二叉树

    1
   / \
  2   5
 / \   \
3   4   6

将其展开为:

1
 \
  2
   \
    3
     \
      4
       \
        5
         \
          6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list

2.思路

题目本质就是把树的左子树全部并到右子树中,虽然没说顺序,但按示例,就是左-中-右了。也就是说,要把root的右子树,放到左子树的最后一个结点的右子树中。至于左右子树,各自的处理,就是标准的递归了。

所以递归函数的步骤可以理解如下:

  1. 当root为空时,不处理;
  2. 递归处理root的左子树; 递归处理root的右子树;(当然左右子树也可以后面再处理)
  3. 当root没有左子树时,无需处理;
  4. 当root有左子树时,要找到最后一个结点last,从root.left开始往下找(因为是已经处理完的,所以root.left只有右子树),循环找right直到最后一个结点即可;
  5. 关键:
    • 将root的右子树移到last的右指针,last.right = root.right;
    • root的左子树移到root的右指针:root.right = root.left;
    • 清空root的左指针:root.left = null;

作者:gousiqi
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/solution/na-ge-wai-mai-de-gong-fu-tu-ran-xiang-tong-liao-by/
来源:力扣(LeetCode)

所以,面对一个问题的时候,理解问题本质和拆分子问题是最重要的。思路明晰了,代码自然就出来了。

3.代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void flatten(TreeNode* root) {
        if(root==nullptr)return;
        flatten(root->left);
        flatten(root->right);
        if(root->left!=nullptr){
            //找到左子树的最后一个节点
            TreeNode* last=root->left;
            while(last->right!=nullptr)last=last->right;
            //把右子树添加为左子树最后一个节点右子树
            last->right=root->right;
            //把左子树添加为根的右子树
            root->right=root->left;
            //把根节点的左子树置为空
            root->left=nullptr;
        }
    }
};

4.语法知识补充

C++判断指针是否为空:

if(root==nullptr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值