题目描述
递归法
方法一
这种方法,不太容易理解。第一步就是递归,后面才是对基本情况的处理。通过递归,直接向下一直递归到叶节点才开始处理。从树的最底部开始处理。相比下面两种处理,这中方法的速度最快。
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
if(root->left) flatten(root->left);
if(root->right) flatten(root->right);
TreeNode* right = root->right;
root->right=root->left;
root->left=NULL;
while(root->right) root = root->right;
root->right = right;
}
};
方法二
也是递归处理。如果左子树不为空,将左子树接到右子树,同时保存下原来的右子树节点。通过循环找到原来的左子树的底部的最右端叶节点,将原来的右子树接到这个节点上。之后迭代处理下一个节点。
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
TreeNode* right = root->right;
if(root->left)
{
TreeNode* temp = root->left;
root->right = root->left;
root->left = NULL;
while(temp && temp->right) temp=temp->right;
temp->right = right;
flatten(root->right);
}
//如果左子树为空,那么上面的处理将出现遗漏,需要下面的处理
if(root->right)
{
flatten(root->right);
}
}
};
非递归法
和递归法的第二种方法差不多。
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
TreeNode* temp_root = root;
while(temp_root)
{
if(temp_root->left)
{
TreeNode* temp = temp_root->left;
while(temp && temp->right) temp = temp->right; //找到左子树的最后一个右节点
temp->right = temp_root->right;//将根节点对应的左子树,接到左树最右边
temp_root->right = temp_root->left;//将左子树变为右子树
temp_root->left = NULL; //将根节点左子树变为空
}
temp_root = temp_root->right;//移动到下一个根节点,循环处理
}
}
};
参考:
https://www.cnblogs.com/grandyang/p/4293853.html
https://blog.csdn.net/sinat_15723179/article/details/81216235