给定一个二叉树,将该二叉树就地(in-place)转换为单链表。单链表中节点顺序为二叉树前序遍历顺序。
#include<iostream>
#include<vector>
using namespace std;
struct TreeNode{
int val;
TreeNode *left; //左孩子指针
TreeNode *right;//右孩子指针
TreeNode(int x) : val(x),left(NULL),right(NULL) {}
};
class Solution{
public:
/*
法1:前序遍历将所有节点加入一个数组中,然后按照索引来链接成一个链表。
但是这种做法不满足就地转换的要求。
*/
void flatten1(TreeNode *root) {
vector<TreeNode> vec_node;
preOrder(root,vec_node);
for(int i = 1; i < vec_node.size(); i++) {
vec_node[i-1]->left = NULL;
vec_node[i-1]->right = vec_node[i];
}
}
void preOrder1(TreeNode *node,vector<TreeNode*> &vec_node) {
if(!node) {
return;
}
vec_node.push_back(node);
preOrder(node->left,vec_node);
preOrder(node->right,vec_node);
}
/*法二,按照先序遍历的方式原地修改*/
void flattern2(TreeNode *root) {
TreeNode *last = NULL;
preOrder(root,last);
}
//last为当前子树先序遍历的最后一个结点
void preOrder2(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; //将该节点的last保存为左子树的last
}
if(right) {
preOrder(right,right_last);
if(left_last) {
left_last->right = right;
}
last = right_last;
}
}
};
int main() {
TreeNode a(1);
TreeNode b(2);
TreeNode c(5);
TreeNode d(3);
TreeNode e(4);
TreeNode f(6);
a.left = &b;
a.right = &c;
b.left = &d;
b.right = &e;
c.right =&f;
Solution s;
s.flatten(&a);
return 0;
}