Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a balanced binary search tree

Is there a method to build a balanced binary search tree?

Example:

1 2 3 4 5 6 7 8 9

       5
      / \
     3   etc
    / \
   2   4
  /
 1

I'm thinking there is a method to do this, without using the more complex self-balancing trees. Otherwise I can do it on my own, but someone probably have done this already :)


Thanks for the answers! This is the final python code:

def _buildTree(self, keys):
    if not keys:
        return None

    middle = len(keys) // 2

    return Node(
        key=keys[middle],
        left=self._buildTree(keys[:middle]),
        right=self._buildTree(keys[middle + 1:])
        )
like image 462
Znarkus Avatar asked May 23 '10 20:05

Znarkus


People also ask

How will you create a balanced binary search tree from unsorted array?

Set The middle element of the array as root. Recursively do the same for the left half and right half. Get the middle of the left half and make it the left child of the root created in step 1. Get the middle of the right half and make it the right child of the root created in step 1.

What is a balance binary tree?

A balanced binary tree, also referred to as a height-balanced binary tree, is defined as a binary tree in which the height of the left and right subtree of any node differ by not more than 1. To learn more about the height of a tree/node, visit Tree Data Structure.


2 Answers

For each subtree:

  • Find the middle element of the subtree and put that at the top of the tree.
  • Find all the elements before the middle element and use this algorithm recursively to get the left subtree.
  • Find all the elements after the middle element and use this algorithm recursively to get the right subtree.

If you sort your elements first (as in your example) finding the middle element of a subtree can be done in constant time.

This is a simple algorithm for constructing a one-off balanced tree. It is not an algorithm for a self-balancing tree.

Here is some source code in C# that you can try for yourself:

public class Program
{
    class TreeNode
    {
        public int Value;
        public TreeNode Left;
        public TreeNode Right;
    }

    TreeNode constructBalancedTree(List<int> values, int min, int max)
    {
        if (min == max)
            return null;

        int median = min + (max - min) / 2;
        return new TreeNode
        {
            Value = values[median],
            Left = constructBalancedTree(values, min, median),
            Right = constructBalancedTree(values, median + 1, max)
        };
    }

    TreeNode constructBalancedTree(IEnumerable<int> values)
    {
        return constructBalancedTree(
            values.OrderBy(x => x).ToList(), 0, values.Count());
    }

    void Run()
    {
        TreeNode balancedTree = constructBalancedTree(Enumerable.Range(1, 9));
        // displayTree(balancedTree); // TODO: implement this!
    }

    static void Main(string[] args)
    {
        new Program().Run();
    }
}
like image 112
Mark Byers Avatar answered Sep 22 '22 15:09

Mark Byers


This paper explains in detail:

Tree Rebalancing in Optimal Time and Space
http://www.eecs.umich.edu/~qstout/abs/CACM86.html

Also here:

One-Time Binary Search Tree Balancing: The Day/Stout/Warren (DSW) Algorithm
http://penguin.ewu.edu/~trolfe/DSWpaper/

If you really want to do it on-the-fly, you need a self-balancing tree.

If you just want to build a simple tree, without having to go to the trouble of balancing it, just randomize the elements before inserting them into the tree.

like image 39
Robert Harvey Avatar answered Sep 20 '22 15:09

Robert Harvey