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
Java Solution
Go down the tree to the left, when the right child is not null, push the right child to the stack.
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public void flatten(TreeNode root) { Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode p = root; while(p != null || !stack.empty()){ if(p.right != null){ stack.push(p.right); } if(p.left != null){ p.right = p.left; p.left = null; }else if(!stack.empty()){ TreeNode temp = stack.pop(); p.right=temp; } p = p.right; } } } |
should have mentioned according what traverse – in post pre?
this example is pre order.
This should be a simple preorder traversal right
public void flatten() {
List list = new ArrayList();
flatten(root, list);
for (Node node: list) {
System.out.print(node.value + " ");
}
}
private void flatten(Node node, List list) {
if (node == null) {
return;
}
list.add(node);
flatten(node.left, list);
flatten(node.right, list);
}
I am working on a way to do this, but I’m starting with a novel array structure that forms a *dense* store of the tree and uses simple formulae for walking it. I have got the up, left and right formulae, even some odd ‘push up and inwards’ functions, but I have to make it so I can walk the array like it is a list, and I have got a formula for finding the rows of each, and if I start from the beginning of the flattened tree, I already know how to find the indices for, as I am calling it, a Bifurcation Array. An array that each subsequent row is double the width of the previous. This is a ‘dense’ representation of a binary tree, and allows you to eliminate the need to store vectors connecting the nodes – the nodes are the only data and the mathematical structure (number theory) tells you their interrelations.
https://github.com/calibrae-project/bast/blob/loki/cmd/treeflattener/main.go#L26 this is the logic that discovers the row positions for each element in the flattened tree. I am trying to figure out how to derive the actual index from the Bifurcation Array. Then I can walk it sideways. The reason I need this is that it is required for the ‘rebalancing’ operations that shift the root from one side to the other, and a function that ‘spreads’ the tree when you need to insert a value and doing so would require adding a new row to the array.
if p==null, p.right blows up
Yes, acccepted.
Is this right?
void flatten(struct TreeNode* root) {
struct TreeNode *temp = NULL;
if(!root)return;
if(root-> left){
flatten(root-> left);
if(root-> right){
flatten(root-> right);
}
temp = root-> left;
while(temp-> right){
temp = temp-> right;
}
temp-> right = root-> right;
root-> right = root-> left;
root-> left = NULL;
}
else{
flatten(root-> right);
}
}
Recursive solution. Time complexity O(N), Space complexity O(H) (H: height of the tree)
public class BinTreeNode {
public final T value;
public BinTreeNode left;
public BinTreeNode right;
}
void flatten(BinTreeNode root) {
flatten(root, null);
}
BinTreeNode flatten(BinTreeNode node, BinTreeNode last) {
if (node == null) return last;
BinTreeNode oldLeft = node.left;
BinTreeNode oldRight = node.right;
node.left = last;
if (last != null) {
last.right = node;
}
last = node;
last = flatten(oldLeft, last);
last = flatten(oldRight, last);
return last;
}
Using recursion is not in-place right? You are using the system stack.
@diegocedrim:disqus your code is good, but missing 1 thing – setting “node.left = nil;” before calling recursion. See http://pastebin.com/ubpZaXqf
Had the same doubt. But since the problem is to “flatten” which means, we need to change the links pointed by the node, we need to do like this. But yeah, preorder gives the same answer.
I mean PreOrder Traversal.
Hi,
I am a tad-bit confused. Isn’t this question very similar to Inorder traversal of a Binary Tree?Will it work if I just did Inorder traversal and stored all that value while doing that? Am I wrong? Please correct me.
There’s a non recursive solution that does not use a container, only an auxiliary variable. The idea is to move the right subtree to the left subtree to free the root’s right node, then move the resulting left subtree to the right side.
very incomplete code, it doesn’t run without those accessory classes.
Just do an inorder traversal and then add the left node to the list. and when the node pops out and u assign right node, assign next to list again.
Just do an inorder traversal and then add the left node to the list. and when the node pops out and u assign right node, assign next to list again.
I wrote a code that not uses any other data structure, but uses recursion.
The basic idea is:
1) Find a node N with a left child L;
2) Find the rightmost descendant of L and call it RM;
3) Aux = N.right;
4) N.right = L
5) RM.right = Aux
6) Explore the right subtree of N recursively.
The code can be seen in http://pastebin.com/AXsgEJs7
is this in place? you are using a stack…, but the solution is indeed nice!