Solution:
When I first see this problem, my first thought was in-order traversal. Couldn’t we modify the nodes’ left and right pointers as we do an in-order traversal of the tree? However, we have to beware not to modify the pointers and accessing it at a later time.
When I first see this problem, my first thought was in-order traversal. Couldn’t we modify the nodes’ left and right pointers as we do an in-order traversal of the tree? However, we have to beware not to modify the pointers and accessing it at a later time.
As we traverse the tree in-order, we could safely modify a node’s left pointer to point to the previously traversed node as we never use it once we reach a node. We would also need to modify the previously traversed node’s right pointer to point to the current node. Note: The previously traversed node meant here is not its parent node. It is the node’s previous smaller element.
Easy approach, right? But wait, we are still missing two more steps. First, we did not assign the list’s head pointer. Second, the last element’s right pointer does not point to the first element (similar to the first element’s left pointer).
How do we solve this? My approach is pretty easy: Just update the current node’s right pointer to point back to the head and the head’s left pointer to point to current node in each recursive call. As the recursion ends, the list’s head and tail would be automagically updated with the correct pointers. Don’t forget to check for this special case: A list with only one element should have its left and right pointers both pointing back to itself.
A double-linked list with a length of one.
Do you think this approach works? I bet it did! The run time complexity for this solution is O(N) since we are essentially doing a modified in-order traversal. It does have some extra assignments in each recursive call though. But overall I am quite satisfied with this approach because it is intuitive and easy to follow. Besides, we are adapting an existing algorithm (in-order traversal) to solve this problem, isn’t this just neat?
Program:static Node previous = null, headList = null; static void treeToList(Node root){ if(root == null) return; if(previous == null && root.left == null && root.right == null) { headList = previous = root; return; } treeToList(root.left); previous.right = root; root.left = previous; previous = root; Node tmp = root.right; headList.left = root; root.right = headList; treeToList(tmp); }
References:
http://leetcode.com/2010/11/convert-binary-search-tree-bst-to.html
or
private static Node convert2DLLUtil(Node root){
if(root == null) return null;
if(root.left != null)
{
Node left = convert2DLLUtil(root.left);
for( ; left.right != null; left = left.right);
left.right = root;
root.left = left;
}
if(root.right != null)
{
Node right = convert2DLLUtil(root.right);
for( ; right.left != null; right = right.left);
right.left = root;
root.right = right;
}
return root;
}
static Node convert2DLL(Node root){
if(root == null) return null;
Node tmp = convert2DLLUtil(root);
for( ;tmp.left != null; tmp = tmp.left);
return tmp;
}
Reference:
http://www.geeksforgeeks.org/in-place-convert-a-given-binary-tree-to-doubly-linked-list/