Flatten Binary Tree to Linked List
Given a binary tree, flatten it to a linked list in place, and each node's right child points to the next node of a preorder traversal.From a recursive view, store the last visited node in a preorder walk, and last visited node'right child points to the current node. Before this, the right child node should be saved.
class Solution {
public:
void flatten(TreeNode *root) {
if(root==NULL) return;
last=NULL;
preOrderFlatten(root);
}
void preOrderFlatten(TreeNode *root){
if(root==NULL) return;
TreeNode *savedRight=root->right;
if(last==NULL)
last=root;
else{
last->right=root;
last->left=NULL;
}
last=root;
preOrderFlatten(root->left);
preOrderFlatten(savedRight); //由于前面可能会改变root->right的值,故这里需先保存
}
private:
TreeNode *last;
};
The second way is to mimic the preorder traversal in a iterative way. similar to the Morris Traversal.
class Solution {
public:
void flatten(TreeNode *root) {
if(root==NULL) return;
last=NULL;
preOrderFlatten(root);
}
void preOrderFlatten(TreeNode *root){
if(root==NULL) return;
TreeNode *savedRight=root->right;
if(last==NULL)
last=root;
else{
last->right=root;
last->left=NULL;
}
last=root;
preOrderFlatten(root->left);
preOrderFlatten(savedRight); //由于前面可能会改变root->right的值,故这里需先保存
}
private:
TreeNode *last;
};
class Solution {
public:
void flatten(TreeNode *root) {
if(root==NULL) return;
while(root){
if(root->left){
TreeNode *rightMost=root->left;
while(rightMost->right)
rightMost=rightMost->right;
rightMost->right=root->right;
root->right=root->left; //事先已经保存好了
root->left=NULL;
}
root=root->right;
}
}
};
The left subtree's last node should points to the root's right child node.
class Solution {
public:
void flatten(TreeNode *root) {
if(root==NULL) return;
while(root){
if(root->left){
TreeNode *rightMost=root->left;
while(rightMost->right)
rightMost=rightMost->right;
rightMost->right=root->right;
root->right=root->left; //事先已经保存好了
root->left=NULL;
}
root=root->right;
}
}
};
Flatten a BST into a sorted doubly linked list (EPI, 315)
Idea 1: store the result of a inorder traversal in a vector, and build the doubly linked list...
Idea 2: Add a auxiliary variable to store the last visited node in both recursive or iterative way.
Idea 3: Without any auxiliary variable, recursively dealing with the left subtree, the root, and the right subtree, This is only applied in the inorder traversal.
//input: root is the refrenced pointer
TreeNode * BST_to_Doubly_list(TreeNode * &root){
if(root==NULL) return NULL;
//as the left subtree and right subtree are independent
TreeNode *lhead=BST_to_Doubly_list(root->left);
TreeNode *rhead=BST_to_Doubly_list(root->right);
//doubly linked list
TreeNode *ltail=NULL;
if(lhead){
ltail=head->left;
ltail->right=root;
root->left=ltail;
ltail=n;
}
else{
lhead=ltail=root;
}
//append the list from the right subtree to root
TreeNode *rtail=NULL;
if(rhead){
rtail=rhead->left;
ltail->right=rhead;
rhead->left=ltail;
}
else{
rtail=ltail;
}
//link the new head and new tail together
rtail->right=lhead;
lhead->left=rtail;
return lhead;
}
//input: root is the refrenced pointer
TreeNode * BST_to_Doubly_list(TreeNode * &root){
if(root==NULL) return NULL;
//as the left subtree and right subtree are independent
TreeNode *lhead=BST_to_Doubly_list(root->left);
TreeNode *rhead=BST_to_Doubly_list(root->right);
//doubly linked list
TreeNode *ltail=NULL;
if(lhead){
ltail=head->left;
ltail->right=root;
root->left=ltail;
ltail=n;
}
else{
lhead=ltail=root;
}
//append the list from the right subtree to root
TreeNode *rtail=NULL;
if(rhead){
rtail=rhead->left;
ltail->right=rhead;
rhead->left=ltail;
}
else{
rtail=ltail;
}
//link the new head and new tail together
rtail->right=lhead;
lhead->left=rtail;
return lhead;
}