当前位置:   article > 正文

114. 二叉树展开为链表_二叉树展开为链表 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的

二叉树展开为链表 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的

题目描述:

给你二叉树的根结点 root ,请你将它展开为一个单链表

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。
 

示例 1:


输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [0]
输出:[0]
 

提示:

树中结点数在范围 [0, 2000] 内
-100 <= Node.val <= 100
 

进阶:你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:

        跟二叉树相关的,大部分都是递归。先明确递归函数的功能,再写代码。

        递归函数f的流程:

        1.从根节点出发,沿着右子树遍历。如果遇到某个节点有左子树,执行以下操作:

        2.调用递归函数f,传入该节点的左节点,展开该左子树,最后返回展开后的第一个节点changeroot

        3.该节点的右子树暂存在tempright中,将该节点的右子树连接到刚刚返回的展开后的左子树第一个节点changeroot。

        4.沿着右子树方向,遍历到changeroot的叶子节点。

        5.叶子节点的右子树连接到刚才暂存下来的真正的右子树tempright

        6.移动到tempright的第一个节点,以该节点为根节点。返回步骤1

 代码如下:

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. void flatten(TreeNode* root) {
  15. // 调用f,展开二叉树
  16. f(root);
  17. return;
  18. }
  19. // 函数f,传入根节点root,返回单链表的根节点
  20. // 功能:沿着右子树进行遍历,如果当前节点有左子树,则递归展开左子树
  21. TreeNode *f(TreeNode* root)
  22. {
  23. if(!root) return NULL;
  24. // 复制root
  25. TreeNode* temp=root;
  26. // 所有左子树转换完毕之前,进行循环
  27. while(temp)
  28. {
  29. // changeroot存储转换左子树后的左子树根节点
  30. TreeNode *changeroot=f(temp->left);
  31. // tempright,暂时存储右子树
  32. TreeNode *tempright=temp->right;
  33. // 右子树暂时替换为转换后的左子树
  34. temp->right=changeroot;
  35. // 左子树为空
  36. temp->left=NULL;
  37. // 在转换后的左子树上,沿着右子树进行遍历,直至遍历完毕转换之后的左子树,到达叶子节点
  38. while(temp&&temp->right)
  39. temp=temp->right;
  40. // 叶子节点连接之前断开的右子树
  41. temp->right=tempright;
  42. // 到达断开的右子树第一个节点,开始进行下一轮循环,转换该节点的左子树
  43. temp=temp->right;
  44. }
  45. // 返回转换左子树之后的根节点
  46. return root;
  47. }
  48. };

看了看题解,题解并没有使用递归函数,而是用迭代的方法完成的。

思路如下:

        1.root不为空的条件下,进行循环。从根节点root出发,如果root的左子树为空,则沿着右子树遍历,直到root的左子树不为空

        2.暂存root的右节点,记为tempright

        3.进入root的左子树,找到左子树的最右端节点,记为pre,该节点也是root右子树的前驱节点(按照前序遍历,该节点的后继节点为root右子树中第一个节点)

        4.tempright挂载到pre的右子树上

        5.root的左子树挂载到root的右子树上

        6.root左子树赋值为空,并且root移动到其右子树上,即root=root->right

        7.返回步骤1,继续循环

题解链接:

https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/solution/er-cha-shu-zhan-kai-wei-lian-biao-by-leetcode-solu/

代码如下:

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode() : val(0), left(nullptr), right(nullptr) {}
  8. * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  9. * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
  10. * };
  11. */
  12. class Solution {
  13. public:
  14. void flatten(TreeNode* root) {
  15. // root不为空时进入循环
  16. while(root!=NULL)
  17. {
  18. // 左节点为空,则往右移动
  19. if(root->left==NULL)
  20. {
  21. root=root->right;
  22. continue;
  23. }
  24. // 左节点不空
  25. // 存下右子树为tempright
  26. TreeNode *tempright=root->right;
  27. // 存下左子树
  28. TreeNode *templeft=root->left;
  29. // 左子树赋值给leftend
  30. TreeNode *leftend=templeft;
  31. // 找到左子树的最右端节点,该节点为root右子树的前驱节点
  32. while(leftend->right!=NULL)
  33. leftend=leftend->right;
  34. // 将右子树挂在其前驱节点上
  35. leftend->right=tempright;
  36. // 左子树挂到号右子树上
  37. root->right=root->left;
  38. // 左子树设置为NULL
  39. root->left=NULL;
  40. // 进入右子树下一个节点,继续遍历
  41. root=root->right;
  42. }
  43. }
  44. };

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/42655
推荐阅读
相关标签
  

闽ICP备14008679号