Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers as synonymous to the previous and next pointers in a doubly-linked list.

asked 29 Nov '10, 21:17

1337c0d3r's gravatar image

1337c0d3r ♦♦
541337139
accept rate: 1%


If the problem statement is still not clear to you, below is a pictorial representation of what you need to do:


i) an ordered binary tree (BST) storing numbers from 1 - 5.


ii) original tree converted to a sorted circular doubly-linked list. Its left and right pointers were modified to point to its previous and next node.

I originally read this interesting problem here: The Great Tree-List Recursion Problem.

Hint:
Think of in-order traversal. How do you ensure that the last element's right pointer points back to the first element?


A circular doubly-linked list. Think of the left and right pointers in a tree as synonymous to the previous and next pointers in a list.

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.

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?

// This is a modified in-order traversal adapted to this problem.
// prev (init to NULL) is used to keep track of previously traversed node.
// head pointer is updated with the list's head as recursion ends.
void treeToDoublyList(Node *p, Node *& prev, Node *& head) {
    if (!p) return;
    treeToDoublyList(p->left, prev, head);
    // current node's left points to previous node
    p->left = prev;
    if (prev)
        prev->right = p;  // previous node's right points to current node
    else
        head = p; // current node (smallest element) is head of
    // the list if previous node is not available
    // as soon as the recursion ends, the head's left pointer
    // points to the last node, and the last node's right pointer
    // points to the head pointer.
    Node *right = p->right;
    head->left = p;
    p->right = head;
    // updates previous node
    prev = p;
    treeToDoublyList(right, prev, head);
}

// Given an ordered binary tree, returns a sorted circular
// doubly-linked list. The conversion is done in-place.
Node* treeToDoublyList(Node *root) {
    Node *prev = NULL;
    Node *head = NULL;
    treeToDoublyList(root, prev, head);
    return head;
}

Alternative Solution:
There is an alternative solution which doesn't use in-order traversal. Instead, it uses a divide and conquer method which is quite neat. I highly recommend you to read the solution (code provided) here.

link

answered 29 Nov '10, 21:17

1337c0d3r's gravatar image

1337c0d3r ♦♦
541337139
accept rate: 1%

The parameter "Node* &prev" is redundant, since it can be replace by "head->left".

My code is implemented by Python:

def BST2List(node, head=None):
    if (node is not None):
        #print "curr node", node.value
        head = BST2List(node.left, head)

        if (head is None):
            head = node
            head.left = node
        else:               
            node.left = head.left
            head.left = node
            node.left.right = node
        right = node.right
        node.right = head

        head = BST2List(right, head)
        #print "head", head.value, "head.left", head.left.value, "head.right", head.right.value
        return head
    else:
        return head
link

answered 29 Jun, 08:34

cydrain's gravatar image

cydrain
11
accept rate: 0%

edited 29 Jun, 08:36


private:

TreeNode* join(TreeNode* a, TreeNode* b)
{
   if (a == NULL) return b;
   else if (b == NULL) return a;
   TreeNode* aRight = a->left;
   TreeNode* bRight = b->left;

   aRight->right = b;
   b->left = aRight;

   bRight->right = a;
   a->left = bRight;

   return a;

}

public :
TreeNode* bst_to_dll(TreeNode* t)
{
    if (t == NULL) return NULL; 
    return join( join( bst_to_dll(t->left), t), bst_to_dll(t->right) ):
}


link

answered 04 Jul, 00:38

fafdu's gravatar image

fafdu
11
accept rate: 0%

edited 04 Jul, 00:40

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • Indent code by 4 spaces.
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×21
×5

Asked: 29 Nov '10, 21:17

Seen: 331 times

Last updated: 04 Jul, 00:40