二叉树转链表
题目[leetcode114]
给定一个二叉树,原地将它展开为一个单链表。
例如,给定二叉树
1
/ \
2 5
/ \ \
3 4 6
将其展开为:
1
\
2
\
3
\
4
\
5
\
6
思路
方法一: 开辟一个vector实现的存储空间,按照前序遍历的顺序将每一个节点存入到节点空间中,之后就是按从头到尾的将每个节点连接在右节点上,即可完成链表的链接。(使用了额外的存储空间)
展示如下:
实现代码如下:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
#include <vector>
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);
}
};
方法二: 将问题拆解并解决子问题,变为一个头节点有左子树和右子树时,该怎么样去解决问题,而解决问题的方式就是应用指针node、left、left_last、right、right_last指向头节点、左子树形成的链表头尾、右子树形成的链表头尾,按照合适的形式node->right = left,left_last->right = right,right_last = NULL完成链表的串连。
其实子问题的一步一步逐层完成,对于最开始一层的单个节点就是可直接串联的,所以可完成。
过程如下:
实现代码如下:
class Solution {
public:
void flatten(TreeNode* root) {
TreeNode* last = NULL;
preorder(root, last);
}
private:
void preorder(TreeNode* node, TreeNode* &last){
if(!node){
return;
}
if(!node->left && !node->right){ //为叶结点时
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; //尾节点为left_last
}
if(right){
preorder(right, right_last);
if(left_last){
left_last->right = right;
}
last = right_last; //尾节点为right_last
}
}
};
致谢
本章知识点和思路由小象学院相关视频提供,由本人学习并梳理得出,希望自己加深记忆的同时,也能给大家提供更多有关于一些算法的知识点。
你的点赞、评论、收藏就是对我最大的支持与鼓励,谢谢!