Create Balanced Binary Search Tree from Sorted linked list

后端 未结 11 1740
囚心锁ツ
囚心锁ツ 2020-12-07 16:48

What\'s the best way to create a balanced binary search tree from a sorted singly linked list?

相关标签:
11条回答
  • 2020-12-07 17:26

    Hope the detailed explanation on this post helps: http://preparefortechinterview.blogspot.com/2013/10/planting-trees_1.html

    0 讨论(0)
  • 2020-12-07 17:27

    You can't do better than linear time, since you have to at least read all the elements of the list, so you might as well copy the list into an array (linear time) and then construct the tree efficiently in the usual way, i.e. if you had the list [9,12,18,23,24,51,84], then you'd start by making 23 the root, with children 12 and 51, then 9 and 18 become children of 12, and 24 and 84 become children of 51. Overall, should be O(n) if you do it right.

    The actual algorithm, for what it's worth, is "take the middle element of the list as the root, and recursively build BSTs for the sub-lists to the left and right of the middle element and attach them below the root".

    0 讨论(0)
  • 2020-12-07 17:32

    Best isn't only about asynmptopic run time. The sorted linked list has all the information needed to create the binary tree directly, and I think this is probably what they are looking for

    Note that the first and third entries become children of the second, then the fourth node has chidren of the second and sixth (which has children the fifth and seventh) and so on...

    in psuedo code

    read three elements, make a node from them, mark as level 1, push on stack
    loop
        read three elemeents and make a node of them
        mark as level 1
        push on stack
        loop while top two enties on stack have same level (n)
             make node of top two entries, mark as level n + 1, push on stack
    while elements remain in list
    

    (with a bit of adjustment for when there's less than three elements left or an unbalanced tree at any point)

    EDIT:

    At any point, there is a left node of height N on the stack. Next step is to read one element, then read and construct another node of height N on the stack. To construct a node of height N, make and push a node of height N -1 on the stack, then read an element, make another node of height N-1 on the stack -- which is a recursive call.

    Actually, this means the algorithm (even as modified) won't produce a balanced tree. If there are 2N+1 nodes, it will produce a tree with 2N-1 values on the left, and 1 on the right.

    So I think @sgolodetz's answer is better, unless I can think of a way of rebalancing the tree as it's built.

    0 讨论(0)
  • 2020-12-07 17:35

    This is the pseudo recursive algorithm that I will suggest.

    
    createTree(treenode *root, linknode *start, linknode *end)
    {
       if(start == end or start = end->next)
       {
          return; 
       } 
       ptrsingle=start;
       ptrdouble=start;
       while(ptrdouble != end and ptrdouble->next !=end)
       {
        ptrsignle=ptrsingle->next;
        ptrdouble=ptrdouble->next->next;
       }
       //ptrsignle will now be at the middle element. 
       treenode cur_node=Allocatememory;
       cur_node->data = ptrsingle->data;
       if(root = null)
           {
               root = cur_node; 
           }
       else
          {
             if(cur_node->data (less than) root->data)
              root->left=cur_node
             else
               root->right=cur_node
          }
       createTree(cur_node, start, ptrSingle);
       createTree(cur_node, ptrSingle, End); 
    }
    
    

    Root = null; The inital call will be createtree(Root, list, null);

    We are doing the recursive building of the tree, but without using the intermediate array. To get to the middle element every time we are advancing two pointers, one by one element, other by two elements. By the time the second pointer is at the end, the first pointer will be at the middle.

    The running time will be o(nlogn). The extra space will be o(logn). Not an efficient solution for a real situation where you can have R-B tree which guarantees nlogn insertion. But good enough for interview.

    0 讨论(0)
  • 2020-12-07 17:36

    Instead of the sorted linked list i was asked on a sorted array (doesn't matter though logically, but yes run-time varies) to create a BST of minimal height, following is the code i could get out:

    typedef struct Node{
         struct Node *left;
         int info;
         struct Node  *right;
    }Node_t;
    
    Node_t* Bin(int low, int high) {
    
         Node_t* node = NULL;
         int mid = 0;
    
         if(low <= high) {
             mid = (low+high)/2;
             node = CreateNode(a[mid]);
             printf("DEBUG: creating node for %d\n", a[mid]);
    
            if(node->left == NULL) {
                node->left = Bin(low, mid-1);
            }
    
            if(node->right == NULL) {
                node->right = Bin(mid+1, high);
            }
    
            return node;
        }//if(low <=high)
        else {
            return NULL;
        }
    }//Bin(low,high)
    
    
    Node_t* CreateNode(int info) {
    
        Node_t* node = malloc(sizeof(Node_t));
        memset(node, 0, sizeof(Node_t));
        node->info = info;
        node->left = NULL;
        node->right = NULL;
    
        return node;
    
    }//CreateNode(info)
    
    // call function for an array example: 6 7 8 9 10 11 12, it gets you desired 
    // result
    
     Bin(0,6); 
    

    HTH Somebody..

    0 讨论(0)
  • 2020-12-07 17:37

    How about creating nodes bottom-up?

    This solution's time complexity is O(N). Detailed explanation in my blog post:

    http://www.leetcode.com/2010/11/convert-sorted-list-to-balanced-binary.html

    Two traversal of the linked list is all we need. First traversal to get the length of the list (which is then passed in as the parameter n into the function), then create nodes by the list's order.

    BinaryTree* sortedListToBST(ListNode *& list, int start, int end) {
      if (start > end) return NULL;
      // same as (start+end)/2, avoids overflow
      int mid = start + (end - start) / 2;
      BinaryTree *leftChild = sortedListToBST(list, start, mid-1);
      BinaryTree *parent = new BinaryTree(list->data);
      parent->left = leftChild;
      list = list->next;
      parent->right = sortedListToBST(list, mid+1, end);
      return parent;
    }
    
    BinaryTree* sortedListToBST(ListNode *head, int n) {
      return sortedListToBST(head, 0, n-1);
    }
    
    0 讨论(0)
提交回复
热议问题