二叉树后序遍历展平
展平左子树
再展平右子树
接入根节点并返回
递归结束条件,该节点为空,为叶节点。
如何接入根节点,我们在展平左右子树后接入根节点,那么只需要找到相应的位置接入即可,首先记录左子树的首节点和尾节点,右子树的首节点,那么我们先将左子树的首节点接入到根节点的右子树,再将右子树的首节点接到左子树的尾节点即可。
/**
* 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) {
// 二叉树中序遍历
flat(root);
}
TreeNode* flat(TreeNode* root){
// 为空时
if(root==nullptr){
return root;
}
TreeNode* l_front = nullptr;
TreeNode* l_rear = nullptr;
TreeNode* r_front =nullptr;
if(root->left!=nullptr&&root->right!=nullptr){
l_front = flat(root->left); // 返回合并后的表头
l_rear = search(l_front); // 返回合并后的表尾
r_front = flat(root->right);
// 接入
root->left = nullptr;
root->right = l_front;
l_rear->right = r_front;
return root;
}else if(root->left!=nullptr&&root->right==nullptr){
root->right = flat(root->left);
root->left =nullptr;// 将当前节点的左子树置空
return root;
}else if(root->right!=nullptr){
root->left = nullptr;
root->right = flat(root->right);
return root;
}
root->left = nullptr;
root->right = nullptr;
return root;
}
// 寻找尾节点
TreeNode* search(TreeNode* root){
if(root == nullptr){
return root;
}
while(root->right!=nullptr){
root=root->right;
}
return root;
}
};