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 \ 6
分析:按照树的先序遍历顺序把节点串联起来即可,代码如下
/**
* 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) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(root == NULL)return ;
stack<TreeNode *> S;
S.push(root);
TreeNode *pre = NULL;
while(S.empty() == false)
{
TreeNode *p = S.top();
S.pop();
if(pre != NULL)
{
pre->right = p;
pre->left = NULL;
}
if(p->right)S.push(p->right);
if(p->left)S.push(p->left);
pre = p;
}
pre->left = NULL;
pre->right = NULL;
}
};
也可以不通过栈的方式。代码如下:
class Solution {
public:
void flatten(TreeNode* root) {
TreeNode* cur = root;
while (cur) {
if (cur->left) {
TreeNode* right = cur->right;
if (right) {
TreeNode* rightMost = cur->left;
while (rightMost->right!=NULL) {
rightMost=rightMost->right;
}
rightMost->right=cur->right;
}
cur->right=cur->left;
cur->left=NULL;
}
cur = cur->right;
}
}
};
2015.9.14更新
-----------------------
这道题目,一开始我打算用morris算法来做,但是后来发现morris算法在这个场景下是不合适的。为什么呢?当root左子树不为空,并且右子树不为空时,指针从root移动到root->left,但是这个时候根本找不到时机让root->right = root->left并且root->left=NULL,因为右子树并不为空。所以这里用morris算法是不合适的。
那么用stack迭代行不行呢,经过分析是可行的,为什么?因为当root弹出之后,root->right和root->left假如不为空的话,都紧跟着将被push进栈。这就为我们调整指针提供了充分的数据(也就是root->right和root->left)。class Solution {
public:
void flatten(TreeNode* root) {
if (!root) {
return;
}
stack<TreeNode*> st;
TreeNode* prev = NULL;
st.push(root);
while (!st.empty()) {
TreeNode* par = st.top();
if (prev) {
prev->right = par;
prev->left = NULL; //必须将left赋值为NULL
}
prev = par;
st.pop();
if (par->right) {
st.push(par->right);
}
if (par->left) {
st.push(par->left);
}
}
}
};