二进制搜索树的非递归遍历以更新大小

时间:2014-04-08 23:55:56

标签: java tree binary-search-tree non-recursive

请原谅我,如果有人问过,但我在搜索时无法找到它。所有搜索结果都是关于遍历二叉树,就好像正在搜索特定节点一样 - 因此它会结束向左或向右走,等等。

但是如何遍历更新树的大小呢?就像你在底部添加了一个新节点一样,你必须更新每个节点的大小以反映新的树大小。

假设这是原始树,你添加Z:

    D              D
   / \            / \
  A   S   -->    A   S
     /              / \
    N              N   Z
(size = 4)      (size = 5)

所以要更新大小,除非我想错了,你必须先更新下面的节点,然后才能更新它上面的节点。对? (要更新D,您必须先更新S和A)

那么,你将如何从根到底遍历,但从下往上更新?

1 个答案:

答案 0 :(得分:0)

我仍然不确定您存储每个子树大小的用例是什么,但是在每次插入过程中很容易保持更新而不诉诸递归。为简单起见,我们假设您从以下定义开始:

public static class BSTNode
{
    public BSTNode leftTree = null;
    public BSTNode rightTree = null;
    public int subtreeSize = 1;
    public int value;

    public BSTNode(int valToAdd){
        value = valToAdd;
    }
}

public static class BST
{
    public BSTNode root;

    //public void insert(int valToAdd)
}

insert的实现中,我们从根开始并遍历树以找到添加新值的适当位置。我们可以随时更新每个子树的大小。一个简单的实现可能如下所示:

public void insert(int valToAdd)
{
    if(root == null){
        root = new BSTNode(valToAdd);
        return;
    }

    BSTNode parent = root;
    BSTNode current = root;
    while(current != null){
        parent = current;
        ++current.subtreeSize;
        if(valToAdd <= current.value){
            current = current.leftTree;
        }
        else{
            current = current.rightTree;                
        }
    }

    if(valToAdd <= parent.value){
        parent.leftTree = new BSTNode(valToAdd);
    }
    else{
        parent.rightTree = new BSTNode(valToAdd);
    }
}

有些情况下,您希望从底部开始更新,例如跟踪子树高度(可能用于重新平衡)。假设BSTNode定义现在是:

public static class BSTNode
{
    public BSTNode leftTree = null;
    public BSTNode rightTree = null;
    public int height = 0;
    public int value;

    public BSTNode(int valToAdd){
        value = valToAdd;
    }
}

insert中,使用Stack(或任何可提供LIFO语义的东西)来存储新插入节点的祖先。修改我们之前的简单示例:

public void insert(int valToAdd)
{
    if(root == null){
        root = new BSTNode(valToAdd);
        return;
    }

    java.util.Stack<BSTNode> stack = new java.util.Stack<BSTNode>();

    BSTNode parent = root;
    BSTNode current = root;
    while(current != null){
        parent = current;
        stack.push(current);
        if(valToAdd <= current.value){
            current = current.leftTree;
        }
        else{
            current = current.rightTree;                
        }
    }

    if(valToAdd <= parent.value){
        parent.leftTree = new BSTNode(valToAdd);
    }
    else{
        parent.rightTree = new BSTNode(valToAdd);
    }

    int height = 1;
    while(!stack.isEmpty()){
        current = stack.pop();
        current.height = Math.max(height, current.height);
        ++height;
    }
}