给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
通过次数43,948提交次数63,581
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
先序遍历二叉树,每个节点先备份两个左右子节点,之后分别向下递归,展开左子树并记录左子树的尾结点,右子树同理,记录右子树的尾结点。之后将当前节点的左子树置空,右子树指向备份的左节点,左节点记录下来的尾结点的右节点指向备份的右子树,这样,在左右子树都展开的情况下,当前节点也被展开。此时考虑递归的出口,即当遍历到叶子节点的时候,可视作只有一个节点的单链表,返回当前节点为尾结点即可。至此递归向上,可展开整个二叉树。值得注意的是,当右子树展开完成的时候,意味着当前的部分展开完成,需要将右子树的尾结点作为包含当前节点的整个子树的尾结点进行返回。同时,二叉树可能存在没有左节点的情况,因此左子树的尾结点就可能为空导致空指针异常,因此在右子树进行链接的时候需要考虑到这个问题。
/**
* 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;
TreeNode *last = nullptr;
preOrder(root,last);
return;
}
void preOrder(TreeNode *node,TreeNode*& last)
{
if(node->left==nullptr&&node->right==nullptr)
{
last = node;
return;
}
TreeNode* left = node->left;
TreeNode* right = node->right;
TreeNode* left_last = nullptr;
TreeNode* right_last = nullptr;
if(left!=nullptr)
{
preOrder(left,left_last);
node->left = nullptr;
node->right = left;
last = left_last;
}
if(right!=nullptr)
{
preOrder(right,right_last);
if(left_last!=nullptr)
{
left_last->right = right;
}
last = right_last;
}
}
};