Balancing a Binary Search Tree using an ArrayList

1.3k Views Asked by At

For a class assignment I am required to add a method to a provided BinarySearchTree class that will balance the binary search tree by storing the values-in order-in an array, and using those values to construct a new tree. However, when I try to run the method I get a nullPointerException. How can I change my methods to properly balance my binary search tree?

I have included my code below (trying to trim it down to only what is necessary for the problem); the two methods at the bottom are the ones I am trying to use for balancing.

package ch08;

import ch05.queues.*;
import java.util.ArrayList;

public class BinarySearchTree<T extends Comparable<T>> implements BSTInterface<T>{

protected BSTNode<T> root;      // reference to the root of this BST
protected LinkedUnbndQueue<T> inOrderQueue; 
protected ArrayList<T> balanceArray;

public BinarySearchTree(){
    root = null;
}

public int reset(int orderType){
    int numNodes = size();

    if (orderType == INORDER){
        inOrderQueue = new LinkedUnbndQueue<T>();
        inOrder(root);
    }
    return numNodes;
}

public T getNext (int orderType){
    if (orderType == INORDER)
        return inOrderQueue.dequeue();
}

    public void balanceTree() {
    int count = reset(INORDER);

    for(int i = 0; i < count; i++) {
        balanceArray.add(getNext(INORDER));
    }
    BinarySearchTree<T> tree = new BinarySearchTree<T>();
    tree.insertTree(0, count - 1);
    this.root = tree.root;
}

public void insertTree(int low, int high){
    if(low == high) {
        add(balanceArray.get(low));
    }
    else if((low + 1) == high) {
        add(balanceArray.get(low));
        add(balanceArray.get(high));
    }
    else {
        int mid = (low + high) / 2;
        add(balanceArray.get(mid));
        insertTree(low, mid - 1);
        insertTree(mid + 1, high);
    }
 }
}
1

There are 1 best solutions below

0
On

I guess the NullPointerException comes from the fact that you never initialize the balanceArray.

You shouldn't declare inOrderQueue and balanceArray as fields (IMHO) because they only relate to one operation. I would use arguments there.

I don't see the class BSTNode, so I assume it is something like this:

public class BSTNode<T extends Comparable<T>> {
    T value;
    BSTNode<T> left;
    BSTNode<T> right;

    public BSTNode(T value, BSTNode<T> left, BSTNode<T> right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }
}

Here's how I would do the balancing:

public class BinarySearchTree<T extends Comparable<T>> {
    protected BSTNode<T> root;      // reference to the root of this BST

    public BinarySearchTree() {
        root = null;
    }

    // creates a tree from a sorted list
    private BinarySearchTree(List<T> list) {
        root = buildTree(list, 0, list.size());
    }

    public BinarySearchTree<T> balancedTree()  {
        List<T> list = new ArrayList<>();
        inOrder(root, list);
        return new BinarySearchTree(list);
    }

    private void inOrder(BSTNode<T> node, List<T> list) {
        if (node != null) {
            inOrder(node.left, list);
            list.add(node.value);
            inOrder(node.right, list);            
        }
    }

    private BSTNode<T> buildTree(List<T> list, int i, int size) {
        if (size == 0) {
            return null;
        } else {
            int half = size/2;
            int mid = i+half;
            return new BSTNode<T>(list.get(mid),
                    buildTree(list, i, half),
                    buildTree(list, mid+1, size-half-1));
        }
    }

    ...
}