Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 函数:这是二叉搜索树吗;奇数平衡;?_Java_Recursion_Binary Search Tree - Fatal编程技术网

Java 函数:这是二叉搜索树吗;奇数平衡;?

Java 函数:这是二叉搜索树吗;奇数平衡;?,java,recursion,binary-search-tree,Java,Recursion,Binary Search Tree,如果左边的奇数子代数==右边的奇数子代数,则该树是“奇数平衡”树 我被困在如何计数和比较两边的奇数键的数量上。如有任何见解,将不胜感激 试图实施@nem的想法: public boolean isOddBalanced() { return (isOddBalanced (root, '0') >= 0); } private int isOddBalanced (Node x, char side) { int count = 0; if (x == nul

如果左边的奇数子代数==右边的奇数子代数,则该树是“奇数平衡”树

我被困在如何计数和比较两边的奇数键的数量上。如有任何见解,将不胜感激

试图实施@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;
}
看看这个

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);
}

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

您可以使用包装器类实现这一点(因为Java是:

现在,您可以做的不是单独计算左奇值节点或右奇值节点,而是每次找到左奇值节点时,只需在
计数中添加1,每次找到右奇值节点时,从
计数中减去1即可。
这意味着,如果树是奇数平衡的,
count
变量将为0

您的代码如下所示:

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
的值,并且仅在以任何方式更改树内容(添加/删除节点,更改节点值)时更新它


这将允许您对每个树结构只计算一次
isOddBalanced()
的值。

因为您想知道左侧奇数子代的数量是否=右侧奇数子代的数量,所以您只需要左右子代之间的差异

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; 
}

你的问题似乎有问题

如果左边的奇数子代数==右边的奇数子代数,则该树是“奇数平衡”树

这意味着您需要比较根节点的左奇数子代数与根节点的右奇数子代数。但是,这不是为树定义属性的常用方法-通常为树中的每个节点定义此类属性。这意味着您需要检查树的每个节点中的奇数平衡

您可以在遍历整个树的一个递归过程中实现这一点,就像@nem所说的那样。不过,您可以稍微改进解决方案

请注意,一旦我们将奇数平衡定义为递归属性,那么如果它的任何子树是不平衡的,那么树就不会是奇数平衡的。因此,在循环时,我们可以检索奇数节点数和平衡点的信息。如果没有用于两个结果的复合容器,我们如何做到这一点?如果一个子树是不平衡的,那么整个树是不平衡的,对吗?因此,我们已经知道整个树是不平衡的,因此不需要关于节点数量的信息。因此,我们可以将这些相互排斥的信息作为单个
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);
}
private int-isOddBalanced(节点x){
//空树是平衡的,它不包含奇数节点
如果(x==null)返回0;
//检查子树;如果有不平衡,则返回树上的状态
int ls=isOddBalanced(x.左);
//如果左子树不平衡,不要测试右子树
如果(ls<0)返回-1;
int rs=isOddBalanced(x.右);
如果(rs<0)返回-1;
//当两者平衡时,测试奇数节点数是否相等
如果(ls!=rs)返回-1;
//返回当前小计
返回ls+rs+((x.key%2==0)?0:1);
}

奇数子代的数量是指持有奇数值的子节点的数量吗?我认为OP需要检查每侧包含奇数值的节点数量是否相等,而不是每侧的节点数量是否相等。这对我来说非常奇怪,我不理解:/!基本上和我做的一样。。。而不是OP想要的。不幸的是,我不能使用任何其他函数/类。请查看我的编辑以获得可能的解决方案。另外,当您说左边的奇数子代数==右边的奇数子代数时,这是否适用于树中的每个节点?也就是说,是否每个子树都必须奇数平衡才能使整个树奇数平衡?这就是我的回答告诉你的方法。或者这仅仅意味着根左边具有奇数值的节点数量必须等于根右边具有奇数值的节点数量?假设你有一个完美的二叉树,其中有7个节点,按顺序排列,'a'到'G'。还假设节点
A
B
E
G
为奇数(即,根节点
D
两侧各有两个奇数节点)。就我所能追踪到的代码而言,它将回答以节点
D
为根的树不是奇数平衡的-节点
A
B
E
是各自父母的左子女(
来自=='l'
),因此它们导致计数器递增,节点
G
是右子女(
comingFrom=='r'
),因此它会使计数器递减,从而得出
oddCount==2
的最终结果。
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; 
}
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);
}