wu :: forums
« wu :: forums - CS: BST TO LL »

Welcome, Guest. Please Login or Register.
May 19th, 2024, 6:47am

RIDDLES SITE WRITE MATH! Home Home Help Help Search Search Members Members Login Login Register Register
   wu :: forums
   riddles
   cs
(Moderators: Eigenray, SMQ, ThudnBlunder, william wu, Icarus, towr, Grimbal)
   CS: BST TO LL
« Previous topic | Next topic »
Pages: 1  Reply Reply Notify of replies Notify of replies Send Topic Send Topic Print Print
   Author  Topic: CS: BST TO LL  (Read 1698 times)
Jonathan_the_Red
Junior Member
**





   
Email

Gender: male
Posts: 102
CS: BST TO LL  
« on: Aug 30th, 2002, 3:22pm »
Quote Quote Modify Modify

What a cute little problem! It takes some thinking, but once you get it, the solution is nice and elegant. I think I'm gonna add this one to my interview repertoire.
 
The problem isn't quite clear on how the "output parameters" first and last are supposed to work... the way I did it, the caller creates a couple of dummy nodes for head and tail pointers and passes them in. Like so:
 
struct node First, Last;
bst2ll(root, &First, &Last);
// at this point, First.right points to the first node in the linked list, while Last.left points to the last.
 


void bst2ll(struct node *root, struct node *first, struct node *last)
{
    if (root->left)
    {
        bst2ll(root->left, first, root);
    }
    else
    {
        root->left = first;
        first->right = root;
    }
 
    if (root->right)
    {
        bst2ll(root->right, root, last);
    }
    else
    {
        root->right = last;
        last->left  = root;
    }
}
 


 
Edit: hidden by color. Others might want to do this without a spoiler.
« Last Edit: Aug 30th, 2002, 3:24pm by Jonathan_the_Red » IP Logged

My arcade cabinet
Jeremiah Smith
Full Member
***



Beep!

   


Posts: 172
Re: CS: BST TO LL  
« Reply #1 on: Aug 30th, 2002, 9:10pm »
Quote Quote Modify Modify

I had to do something like this once, in my CS class.
IP Logged
TimMann
Senior Riddler
****






   
WWW

Gender: male
Posts: 330
Re: CS: BST TO LL  
« Reply #2 on: Sep 1st, 2002, 1:11am »
Quote Quote Modify Modify

Extension: Can you do the same thing in constant space? (The given solution is recursive, which of course makes it take call stack space proportional to the depth of the tree.) If so, how; if not, why not?
 
 
IP Logged

http://tim-mann.org/
TimMann
Senior Riddler
****






   
WWW

Gender: male
Posts: 330
Re: CS: BST TO LL  
« Reply #3 on: Sep 9th, 2002, 10:53pm »
Quote Quote Modify Modify

Here's a nonrecursive, constant space solution.  It's not nearly as pretty as the recursive solution.  The code is untested, so let me know if you notice errors.  Don't bother letting me know that "goto" is considered harmful.  :-)
 
Anyone know why I can't get YaBB to do the indentation right in "pre" format?  It eats the first few spaces when a line starts with 7 or 8.
 
 
struct node First, Last;
bst2ll(root, &First, &Last);
// at this point, First.right points to the first node in the linked list,  
// while Last.left points to the last.
 
void bst2ll(struct node *root, struct node *first, struct node *last)
{
    struct node *above, *cur, *below;
 
    first->left = NULL;
    first->right = last;
    last->left = first;
    last->right = NULL;
 
    above = NULL;
    cur = root;
 
    /* Try to go down to the left */
 down_left:
    if (cur == NULL) return;
    below = cur->left;
    cur->left = above;  // save how to get back up
    if (below) {
   above = cur;
   cur = below;
   goto down_left;
    }
 
 down_right:
    above = cur->left; // recall how to get back up
    below = cur->right;     // save how to go down to the right
 
    /* Add cur to the list */
    cur->left = last->left;
    last->left = cur;
    cur->left->right = cur;
    cur->right = last;
 
    /* Try to go down to the right */
    /* We leave "above" alone because we don't want to return
  to cur anymore -- it's been removed from the tree and
  placed in the list.  Instead, we want to return to the
  nearest ancestor of cur whose right child we haven't
  yet checked.  This is "above". */
    if (below) {
   cur = below;
   goto down_left;
    }
 
    /* Go back up */
    cur = above;
    goto down_right;
}

IP Logged

http://tim-mann.org/
Grimbal
wu::riddles Moderator
Uberpuzzler
*****






   


Gender: male
Posts: 7527
Re: CS: BST TO LL  
« Reply #4 on: May 30th, 2004, 1:28pm »
Quote Quote Modify Modify

on Sep 1st, 2002, 1:11am, TimMann wrote:
Extension: Can you do the same thing in constant space? (The given solution is recursive, which of course makes it take call stack space proportional to the depth of the tree.) If so, how; if not, why not?

 
Here is a solution.  I changed the type for first of last to the more logical pointer-to-pointer.
 
void bst2ll(struct node *root, struct node **first, struct node **last)
{
    // hidden code

    struct node *prev, *curr, *tmp;
 
    *first = *last = NULL;
    curr = root;
    prev = NULL;
 
    while( curr ){
        while( (tmp = curr->left) ){
            curr->left = tmp->right;
            tmp->right = curr;
            curr = tmp;
        }
        if( !prev )
            *first = curr;
        curr->left = prev;
        prev = curr;
        curr = curr->right;
    } while( curr );
 
    *last = curr;

}
 
It is O(n) because the code in the inner while increments the length of the right edge of the tree, i.e. the list of nodes reachable following the 'right' pointers.
« Last Edit: May 30th, 2004, 1:29pm by Grimbal » IP Logged
Pages: 1  Reply Reply Notify of replies Notify of replies Send Topic Send Topic Print Print

« Previous topic | Next topic »

Powered by YaBB 1 Gold - SP 1.4!
Forum software copyright © 2000-2004 Yet another Bulletin Board