题目:
Given a binary tree, flatten it to a linked list in-place.
For example,
Given
1 / \ 2 5 / \ \ 3 4 6
The flattened tree should look like:
1 \ 2 \ 3 \ 4 \ 5 \ 6Hints:
If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.
提示:如果仔细观察转换后的树会发现,每个结点的右孩子是前序遍历二叉树时的后继。
思路:
非递归版可以参考二叉树的前序遍历:http://blog.csdn.net/u012243115/article/details/42000877 。
非递归版代码1:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void flatten(TreeNode *root)
{
if(root == NULL)
return;
stack<TreeNode *> s;
s.push(root);
while(!s.empty())
{
TreeNode *p = s.top();
s.pop();
//把当前结点的左右孩子入栈
if(p->right)
s.push(p->right);
if(p->left)
s.push(p->left);
//把当前结点的左孩子置空,右孩子置为栈顶结点
p->left = NULL;
if(!s.empty())
p->right = s.top();
}
}
};
非递归版本代码2:
通过观察可以发现前序遍历时,当前结点 root 的右孩子的前驱是以 root 的左孩子为根结点的子树的最右下方的结点。因此可以通过把root 的右孩子设为 最右下方的结点的 next ,然后把左孩子设置为 root 的next ,即相当于同时设置链表的头和尾。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void flatten(TreeNode *root)
{
if(root == NULL)
return;
while(root)
{
if(root->left)
{
TreeNode *pre = root->left;
//找到以左孩子为根结点的子树的最右下方的结点
while(pre->right)
pre = pre->right;
pre->right = root->right;//把root的右孩子设置为此结点的next(链表中的叫法)
root->right = root->left;//把root的左孩子设置为root的next
root->left = NULL;//把root的left置为空,这样设置完之后实际上是同时设置链表的头和尾
}
root = root->right;
}
}
};