Java - 用“蛮力”平衡二叉树

时间:2016-03-19 02:46:23

标签: java algorithm recursion tree binary-search-tree

我正在尝试用Java编写一个平衡二叉树的方法,如下所述:

  

...写一个inorder遍历树   到一个数组,然后使用递归方法(很像二进制搜索)插入数组的中间元素作为根,然后构建平衡的左右子树。

然而,我对如何一起做这件事感到难过。到目前为止,我尝试了各种方法,但没有任何效果。

我还有一个inOrder迭代器,它返回树中所有元素的ArrayList,这样就可以了。

这是我目前正在建立的:

public void rebalance()
{
    Iterator<T> it = iteratorInOrder();
    List<T> list = new ArrayList<>();

    while (it.hasNext())
    {
        list.add(it.next());
    }
    balanceRecursive( );
}

private void balanceRecursive( )
{
    //something here
}

然后我只是在add / remove元素方法的末尾有这个:

if ((getHeight() - getMinHeight()) > 5)
            rebalance();

那么,我怎么能这样呢?

3 个答案:

答案 0 :(得分:0)

在平衡树中,右侧和左侧子树的大小最多相差1个元素。给定一个排序数组 - 由您的inorder-traversal生成 - 这变得非常简单。基本思想是构建一个实际的树,它等于二进制搜索隐式遍历的树。从根数组的中间元素开始,中间左边的子数组的中间元素成为左子元素,右子元素的相同模式。使用数组的左半部分相应地将左子项作为根构建子树,对于右子树也是如此。

//lower and upper are the INCLUSIVE bounds of the sublist, from which the tree should be built
Node<T> buildRecursively(int lower , int upper , List<T> elements){
    //no more nodes can be produced on this path
    if(lower > upper)
        return null;

    //build node from the middle-element of the elements
    int middle = (lower + upper) / 2;
    Node<T> result = new Node<>(elements.get(middle));

    //build left and right child for the according pieces of the array/list
    result.setLeftChild(buildRecursively(lower , middle - 1 , elements);
    result.setRightChild(buildRecursively(middle + 1 , upper , elements);

    return result;
}

//build entire tree:
Node<T> root = buildRecursively(0 , elements.size() - 1 , elements);

使用实际数组时,它将如下所示:

             sorted ascending--------->
                         4
                2                6
             1     3          5     7
indices:     0  1  2     3    4  5  6

答案 1 :(得分:0)

  1. 使用中间数组元素作为其值构建节点。
  2. 递归地将(1)应用于数组的左侧部分,并将节点设置为根节点的左子节点。
  3. 将(1)应用于数组的右侧部分,递归,并将节点设置为根节点的右子节点。

答案 2 :(得分:0)

通过按顺序遍历List后,这变得相对简单。 sublist操作意味着您甚至不需要传递索引:

Node<T> buildBalancedTree(List<T> values) {
    if (values.isEmpty()) {
        return Node.NULL;
    } else {
        int middle = values.size() / 2;
        Node node = new Node(values.get(middle));
        node.setLeft(buildBalancedTree(values.subList(0, middle)));
        node.setRight(buildBalancedTree(values.subList(middle + 1, values.size())));
        return node;
    }
}

我假设你有一个Node.NULL代表空子树而不是'null',因为你应该: - )

所以你的重新平衡方法看起来像是:

root = buildBalancedTree(root.getListOfValuesInOrder());