给定一个二叉树,原地将它展开为链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
给定一个二叉树,将该二叉树就地转化为单链表。单链表中节点顺序为二叉树前序遍历顺序
思考:
前序遍历二叉树,将节点指针push进入vector,顺序遍历vector中的节点,链接相邻两节点,形成单链表。按顺序遍历vector,将前面的节点左指针置空,右指针与后面的节点相连,该方法虽然可以通过题目,但不满足就地转化的条件,实现代码如下:
//单链表仍使用该数据结构,即left = NULL, right = next
class Solution {
public:
void flatten(TreeNode* root) {
std::vector<TreeNode *> node_vec;
preorder(root, node_vec);
for (int i = 1; i < node_vec.size(); i++){
node_vec[i-1]->left = NULL;
node_vec[i-1]->right = node_vec[i];
}
}
private:
void preorder(TreeNode *node, std::vector<TreeNode *> &node_vec){
if(!node){
return;
}
node_vec.push_back(node);
preorder(node->left, node_vec);
preorder(node->right, node_vec);
}
};
就地逆转二叉树转链表的代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//单链表仍使用该数据结构,即left = NULL, right = next
class Solution {
public:
void flatten(TreeNode* root) {
TreeNode *last = NULL; //每次递归调用后的最后一个last指针
preorder(root, last);
}
private:
void preorder(TreeNode *node, TreeNode *&last){
//node为当前的节点
//last为当前子树的先序遍历的最后一个节点,传引用会传出
if (!node){
return;
}
if (!node->left && !node->right){ //如果是一个叶节点,无左右子树,则last为本身,直接return
last = node;
return;
}
TreeNode *left = node->left; //备份左右指针
TreeNode *right = node->right;
TreeNode *left_last = NULL; //设置左右子树最后一个节点的变量
TreeNode *right_last = NULL;
if (left){
preorder(left, left_last); //若有左子树,递归将左子树转化单链表
node->left = NULL; //左指针赋空
node->right = left; //完成左子树对应根节点的链接
last = left_last; //将该节点的last保存为左子树的last
}
if (right){ //若有右子树,递归将右子树转换单链表
preorder(right, right_last);
if (left_last){ //若node找到左子树最后一个节点(有左子树)
left_last->right = right; //左子树尾巴和右子树头部的链接
}
last = right_last; //传出最后一个节点的指针,给调用它递归的函数
}
}
};