题目概述
原题链接

树定义如下:
/**
* 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) {}
* };
*/
思考过程
- 由于题目要求展开后的单链表应该同样使用
TreeNode,说明这题的本质是构造一颗只有右子树的树,节点顺序为原树的前序遍历 - 如示例1一颗复杂的树,有点感到无从下手,但如果这棵树只有
根节点、左孩子、右孩子是不是就容易解决多了
1
root.left / \ root.right
2 3
- 如上一步所示,我们只需要将根节点的右孩子指针指向左孩子,再将右孩子拼接到左孩子下,即可完成。需要注意的是
- 在将根节点的右孩子指针指向左孩子前,需要一个临时指针指向右孩子,即
TreeNode* temp=root.right,否则右孩子信息将会丢失,无法进行后续拼接 - 当将根节点的右孩子指针指向左孩子时,此时根节点
1的两个指针都指向了左孩子2,故需要断开原来的连接,即root.left=null - 然后递归找到目前根节点指向的孩子
2的最后一个节点,将用临时指针指向的节点3拼接上去,即可完成这棵树的链表展开了

- 在将根节点的右孩子指针指向左孩子前,需要一个临时指针指向右孩子,即
- 既然一个简单树可以这么做,很显然可以利用
递归的思想解决一颗复杂的树
代码实现
void flatten(TreeNode* root) {
// 特殊情况
if (root == nullptr) return ;
// 捋直左子树
flatten(root->left);
// 捋直右子树
flatten(root->right);
// 临时指针指向右子树
TreeNode* temp = root->right;
// 将左子树接到右子树下,即将右子树的指针指向左子树
root->right = root->left;
// 将左子树置空
root->left = nullptr;
// 找到当前右子树(拼接了左子树的右子树)的最后一个节点
while(root->right != nullptr) {
root = root->right;
}
// 把右子树(原来的)拼接到当前右子树(拼接了左子树的右子树)下
root->right = temp;
}
二叉树扁平化算法

本文介绍了一种将任意二叉树转换为单链表的方法,通过递归地调整树结构,使得每个节点只拥有一个右子节点,并保持节点的前序遍历顺序不变。
430

被折叠的 条评论
为什么被折叠?



