功能:这是二元搜索树"奇数平衡"?

时间:2015-01-21 20:41:11

标签: java recursion binary-search-tree

如果左边是奇数后代的数量==右边是奇数后代的数量,那么这棵树就是#34;奇数平衡"。

public boolean isOddBalanced() {   
    return (isOddBalanced (root) >= 0);
}
private int isOddBalanced (Node x) {
    if (x == null) return 0;
    int ls = isOddBalanced (x.left);
    int rs = isOddBalanced (x.right);
    if (Math.abs (ls - rs) > 0) return -1;
    else return 0;
}

我坚持如何计算&比较每侧奇数键的数量。任何见解都将不胜感激。

尝试从@nem实现想法:

public boolean isOddBalanced() {   
    return (isOddBalanced (root, '0') >= 0);
}
private int isOddBalanced (Node x, char side) {
    int count = 0;
    if (x == null) return 0;
    count = isOddBalanced (x.left, 'l');
    count = isOddBalanced (x.right, 'r');
    if (x.key % 2 != 0 && side == 'l') count += 1;
    if (x.key % 2 != 0 && side == 'r') count -= 1;
    if (count != 0) return -1;
    else return 0;
}

4 个答案:

答案 0 :(得分:2)

您缺少的是一种通过递归计算奇数值节点的方法。

您可以使用包装类来实现此目的(因为Java是pass-by-value):

class OddCounter {
    int count = 0;
}

现在你可以做什么,而不是分别计算左或右奇数值节点,你可以在每次找到左奇数值节点时向count添加1,并从{减去1}每次找到正确的奇数值节点时{1}}。 这意味着,如果树是奇数平衡的,count变量将为0。

您的代码看起来像这样:

count

根据您的评论

编辑(不使用任何额外的课程或功能)

您可以使用实例变量而不是计数器类:

public boolean isOddBalanced() { 
    OddCounter c = new OddCounter();  
    isOddBalancedHelper(root, c, '0');
    return (c.count == 0);
}

private void isOddBalancedHelper (Node x, OddCounter c, char comingFrom) {
    if (x == null) return;
    isOddBalancedHelper(x.left, c, 'l');  
    isOddBalancedHelper(x.right, c, 'r'); 
    if(x.value % 2 != 0 && comingFrom == 'l') {        // if current node is odd and a left child
        c.count++;
    } else if(x.value % 2 != 0 && comingFrom == 'r') { // if current node is odd and a right child
        c.count--;
    }
}

您可以做的另一项改进是兑现int oddCount; // use an instance variable to count the difference between the amount of left odd-nodes and right odd-nodes public boolean isOddBalanced() { this.oddCount = 0; // reset count each time balance is calculated to ensure answer is correct each time (and not just on the first call) isOddBalancedHelper(root, '0'); return (this.oddCount == 0); } private void isOddBalancedHelper (Node x, char comingFrom) { if (x == null) return; isOddBalancedHelper(x.left, 'l'); isOddBalancedHelper(x.right, 'r'); if(x.value % 2 != 0 && comingFrom == 'l') { // if current node is odd and a left child this.oddCount++; } else if(x.value % 2 != 0 && comingFrom == 'r') { // if current node is odd and a right child this.oddCount--; } } 的值,只有在以任何方式更改树内容(添加/删除节点,更改节点值)时才更新它。

这样您就可以只为每个树结构计算一次oddCount的值。

答案 1 :(得分:1)

看看这个。

private int countNode(Node x){
    if(x == null) return 0;
    else return countNode(x.left) + countNode(x.right) + 1;
}

private bool isOddBalanced(Node x){
    int ls = countNode(x.left);
    int rs = countNode(x.right);
    return (ls == rs);
}

答案 2 :(得分:1)

由于你想知道左边的奇数后代的数量= =右边的奇数后代的数量,你只需要左右孩子之间的差异。

public boolean isOddBalanced() {   
    return (CountChilds(root.left) == CountChilds(root.right));
}
private int CountChilds(Node x) {
    if (x == null) return 0;
    // left childs + right childs + me
    else return CountChilds(x.left) + CountChilds(x.right) + 1; 
}

答案 3 :(得分:0)

你的问题似乎不明确。

  

如果左边是奇数后代的数量==右边是奇数后代的数量,那么这棵树就是#34;奇数平衡"。

这意味着您需要将根节点的左奇数后代的数量与根节点的右奇数后代的数量进行比较。然而,这不是定义树的特性的常用方法 - 这些属性通常是为树中的每个节点定义的。这意味着您需要检查树的每个节点中的奇数平衡。

你可以在遍历整个树的单个递归传递中执行此操作,就像@nem所说的那样。但是,您可以稍微改进一下解决方案。

注意,一旦我们将奇数余额定义为递归属性,那么如果树的子树不平衡,那么树将不会是奇数平衡的。因此,在重复发生时,我们可以检索天平上奇数节点的数量。如果没有复合容器,我们怎么能做到这两个结果呢?好吧,如果一个子树不平衡,整棵树都是不平衡的,对吧?所以我们已经知道整棵树是不平衡的,因此不需要有关节点数量的信息。因此,我们可以将这些mutualy独占信息作为单个int值返回:奇数平衡子树中奇数节点数为零或为正,或者对于不平衡子树为负数。

private int isOddBalanced (Node x) {
    // empty tree is balanced and it contains no odd nodes
    if (x == null) return 0;

    // check subtrees; if any is unbalanced, return the status up the tree
    int ls = isOddBalanced (x.left);
    // don't test the right subtree if the left one is unbalanced
    if (ls < 0) return -1;

    int rs = isOddBalanced (x.right);
    if (rs < 0) return -1;

    // when both are balanced test for odd-nodes numbers equality
    if (ls != rs) return -1;

    // return the current sub-total
    return ls + rs + ((x.key % 2 == 0) ? 0 : 1);
}