力扣-114-二叉树展开为链表
题目分析:将二叉树展开为单链表,单链表中各个节点的顺序即为二叉树前序遍历的顺序,故可以通过二叉树的前序遍历获得单链表各个节点的顺序。但是将二叉树转化为单链表后就破坏了二叉树的结构,所以可以保存前序遍历的结果,然后分别依次更改节点的左右节点的信息。
二叉树的前序遍历用递归的方法,代码如下:
/** * 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) { vector<TreeNode*> tree; preorder(root, tree); int num = tree.size(); for(int i = 1; i < num; i++){ //依次更改每个节点的左右节点信息 TreeNode* pre = tree[i - 1]; //tree.at(i - 1); TreeNode* curr = tree[i]; pre->left = NULL; pre->right = curr; } } void preorder(TreeNode* root, vector<TreeNode*>& tree){ //前序遍历 if(root != NULL) { tree.push_back(root); preorder(root->left, tree); preorder(root->right, tree); } } };
方法二:如何在不存储节点增加额外空间的前提下,空间复杂度为$O(1)$的做法
具体做法是,对于当前节点,如果其左子节点不为空,则在其左子树中找到最右边的节点,作为前驱节点,将当前节点的右子节点赋给前驱节点的右子节点,然后将当前节点的左子节点赋给当前节点的右子节点,并将当前节点的左子节点设为空。对当前节点处理结束后,继续处理链表中的下一个节点,直到所有节点都处理结束。
那么问题就转化为了求一个节点的前驱结点,即左子树的最右节点,代码如下:
/*利用前驱节点(即其左子树中最右边的节点)*/ /** * 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) { TreeNode* curr = root; while(curr != NULL) { if (curr->left != NULL) { TreeNode* Left = curr->left; TreeNode* temp = Left; while(temp->right != NULL){ //找到左子树中最右边的节点 temp = temp -> right; } temp->right = curr->right; curr->right = Left; curr->left = NULL; } curr = curr->right; //左子树为空,直接移动到下一个当前节点 } } };
作者:Ryanjie
出处:http://www.cnblogs.com/ryanjan/
本文版权归作者和博客园所有,欢迎转载。转载请在留言板处留言给我,且在文章标明原文链接,谢谢!
如果您觉得本篇博文对您有所收获,觉得我还算用心,请点击右下角的 [推荐],谢谢!