当前位置: 首页 > 知识库问答 >
问题:

在二叉查找树中实现nodeCount()和folCount()

慕容玉堂
2023-03-14

我正在尝试将leafCount()和nodeCount()实现到这个递归二叉树程序中。在测试时,这两种方法(或它们的测试)都会失败,因此显然它们没有按预期工作。我搞不清自己哪里做错了,哪里想错了。如果有人能解释我做错了什么或指出问题所在,我将非常感激。

public class BSTrec {

    BSTNode tree, parent, curr;
    
    public BSTrec () {
        tree = null;    // the root of the tree
        parent = null;  // keeps track of the parent of the current node
        curr = null;    // help pointer to find a node or its place in the tree
    }
    
    public boolean isEmpty() {
        return tree == null;
    }
    
    private boolean findNodeRec(String searchKey, BSTNode subtree, BSTNode subparent) { 
        
        // recursive help method to find a node or its insertion place
        
        if (subtree == null) { // base case 1: node not found
            curr = null;
            parent = subparent; // the logical parent for the value
            return false;
        }
        else { // we are still in the tree
            if (subtree.info.key.equals(searchKey)) { // base case 2: found the node
                curr = subtree;     // update current to point to the node
                parent = subparent; // update parent to point to its parent
                return true;
            }
            else { // must choose the right subtree to search
                if (searchKey.compareTo(subtree.info.key) < 0) { 
                    // key less than current info: search the left subtree!
                    return findNodeRec(searchKey, subtree.left, subtree);
                }
                else { // key greater than current info: search the right subtree!
                    return findNodeRec(searchKey, subtree.right, subtree);  
                }
            }
        }
    }
    
    
    public NodeInfo retrieveNode(String searchKey) { 
        // retrieve the info part of the node with key
        // if it is in the tree
        if (findNodeRec(searchKey, tree, null)) return curr.info;
        else return null;
       
    }                                     
    
    public void addRec(String keyIn, BSTNode subtree, BSTNode subparent, boolean goLeft) {
        
        if (tree == null) { // a first node will be the new root: base case 1
            tree = new BSTNode(new NodeInfo(keyIn));
            curr = tree;
            parent = null;
        } // the tree was initiated, we got a new root
        else { // insertion in an existing tree
            if (subtree == null) { // we found the insertion place: base case 2
                if (goLeft) { // the new node is to be a left child
                    subparent.left = new BSTNode(new NodeInfo(keyIn));
                    curr = subparent.left;
                    parent = subparent; 
                }
                else { // the new node is to be a left child
                    subparent.right = new BSTNode(new NodeInfo(keyIn));
                    curr = subparent.right;
                    parent = subparent;
                }
            }
            else { // still searching for the insertion place: left or right subtree?
                if (keyIn.compareTo(subtree.info.key) < 0) {
                    addRec(keyIn, subtree.left, subtree, true);
                    // the node must be inserted in the left subtree of the
                    // current node: a recursive call
                }
                else { 
                    addRec(keyIn, subtree.right, subtree, false);
                    // the node must be inserted in the right subtree of the
                    // current node: a recursive call
                }
            }
        }
    }
    
    public void deleteNode(String searchKey) { 
        
        // deletes the node with the given key, uses a recursive search
    
        boolean found = findNodeRec(searchKey, tree, null);
        
        if (!found) // the key is not in the tree
            System.out.println("The key is not in the tree!");
        else { // curr points to the node to be deleted, parent to its parent
            if ((curr.left == null) && (curr.right == null)) // delete a leaf
                if (parent == null)  // delete the last node
                    tree = null;
                else // the leaf to be deleted is not the root   
                    if (curr == parent.left) // delete a left child
                        parent.left = null;
                    else                     // delete a right child
                        parent.right = null;
            else // delete a node with children, one or two
                if ((curr.left != null) && (curr.right != null)) { // two children
                    BSTNode surrogateParent = curr;
                    BSTNode replacement = curr.left;
                    while (replacement.right != null) {
                        surrogateParent = replacement;
                        replacement = replacement.right;
                    }
                // the greatest value of the left subtree is chosen as a replacement
                    curr.info = replacement.info; // the information is copied over
                // replacement must now be deleted. It has no children, or a left child.
                    if (curr == surrogateParent) {
                        // there was no right path in the left subtree
                        curr.left = replacement.left; // curr "adopts" the left
                        // child, if any, of the replacement. The replacement is jumped over.
                        replacement = null;
                    }
                    else  { // there was a right path in the left subtree
                        surrogateParent.right = replacement.left;
                        // replacement, the right child of its parent, is jumped over.
                        // The parent "adopts" its left child, if any.
                        replacement = null;
                    }
                } // End: if two children
                else { // delete a node with one child
                    if (parent == null)   // delete a root with one child
                        if (curr.left != null)  // there is a left child
                            tree = curr.left;   // update root
                        else                    // there is a right child
                            tree = curr.right;  // update root
                    // end: the node to be deleted was a root with one child
                    else  // delete a non-root node with one child
                        if (curr == parent.left)    // delete a left child ...
                            if (curr.right == null) // ... with a left child
                                parent.left = curr.left; 
                                // the parent "adopts" the grandchild           
                            else                    // ... with a right child
                                parent.left = curr.right; 
                                // The parent "adopts" the grandchild 
                        else // delete a right child ...
                            if (curr.right == null) // ... with a left child
                                parent.right = curr.left; 
                                // the parent "adopts" the grandchild
                            else                    // ... with a right child
                                parent.right = curr.right; 
                                // The parent "adopts" the grandchild
                } // end: else a node with one child
                curr = null; // curr no longer points to the deleted node
        }
    } // method
    
                
    public void inOrder(BSTNode root) {
        if (root != null) { // implicit base case: empty tree: do nothing
            inOrder(root.left); // process the left subtree
            System.out.println(root.info.key); // process the node itself
            inOrder(root.right); // process the right subtree
        }
    }
    
    public void preOrder(BSTNode root) {
        if (root != null) { // implicit base case: empty tree: do nothing
            System.out.println(root.info.key); // process the node itself
            preOrder(root.left);  // process the left subtree
            preOrder(root.right); // process the right subtree
        }
    }
    
    public void postOrder(BSTNode root) {
        if (root != null) { // implicit base case: empty tree: do nothing
            postOrder(root.left);  // process the left subtree
            postOrder(root.right); // process the right subtree
            System.out.println(root.info.key); // process the node itself
        }
    }
    
    public int nodeCount() {
    int count = 0;

    if (tree == null) {
        count = 0;
        //throw new NullPointerException();
    }
    else {
    if (tree.left != null) {
        count = 1;
        count += tree.left.nodeCount();
    }
    if (tree.right != null) {
        count = 1;
        count += tree.right.nodeCount();
    }
    }
    return count;
}
    
    public int leafCount() {
        int count = 0;

    if (tree != null && tree.left == null && tree.right==null) {
    return 1;
} else {
    if (tree.left != null) // added check
        count += tree.left.leafCount();
    if (tree.right != null) // added check
        count += tree.right.leafCount();
}

    return count; 
}
    
    private class BSTNode {
        NodeInfo info;
        BSTNode left, right;
        
        BSTNode(NodeInfo dataIn) {
            info = dataIn;
            left = null;
            right = null;
        }

    public int leafCount() {
        // TODO Auto-generated method stub
        return 0;
    }

    public int nodeCount() {
        // TODO Auto-generated method stub
        return 0;
    }
    
        /*
        BSTNode(NodeInfo dataIn, BSTNode l, BSTNode r) { // for test constructions
            info = dataIn;
            left = l;
            right = r;
        }
        */
    }

}

public class NodeInfo { // so that this type can be returned String key; // add other fields as needed!

        NodeInfo() {
                key = null;
        }

        NodeInfo(String keyIn) {
                key = keyIn;
        }

}

import static org.junit.Assert.assertTrue;

import org.junit.Test;


public class BSTrecTest { ```

    @Test
    public void testLeafCount() {
        BSTrec tree = new BSTrec();
        assertTrue("The number of leafs should be 0", tree.leafCount() == 0);
        tree.addRec("b", tree.tree, tree.parent, true);
        assertTrue("The number of leafs should be 1", tree.leafCount() == 1);
        tree.addRec("a", tree.tree, tree.parent, true);
        tree.addRec("e", tree.tree, tree.parent, true);
        tree.addRec("f", tree.tree, tree.parent, true);
        tree.addRec("g", tree.tree, tree.parent, true);
        assertTrue("The number of leafs should be 2", tree.leafCount() == 2);
        tree.addRec("c", tree.tree, tree.parent, true);
        /*
         *   b
         *  / \
         * a   e
         *    / \
         *   c   f
         *        \
         *         g
         */
        assertTrue("The number of leafs should be 3", tree.leafCount() == 3);
    }
    
    @Test
    public void testNodeCount() {
        BSTrec tree = new BSTrec();
        assertTrue("The number of nodes should be 0", tree.nodeCount() == 0);
        tree.addRec("b", tree.tree, tree.parent, true);
        assertTrue("The number of nodes should be 1", tree.nodeCount() == 1);
        tree.addRec("a", tree.tree, tree.parent, true);
        tree.addRec("e", tree.tree, tree.parent, true);
        tree.addRec("f", tree.tree, tree.parent, true);
        tree.addRec("g", tree.tree, tree.parent, true);
        assertTrue("The number of nodes should be 5", tree.nodeCount() == 5);
        tree.addRec("c", tree.tree, tree.parent, true);
        /*
         *   b
         *  / \
         * a   e
         *    / \
         *   c   f
         *        \
         *         g
         */
        assertTrue("The number of nodes should be 6", tree.nodeCount() == 6);
    }
    
}


共有1个答案

左丘成仁
2023-03-14

请按照老师的要求尝试实施以下两种方法:

public int leafCount() {
    // TODO Auto-generated method stub
    return 0;
}

public int nodeCount() {
    // TODO Auto-generated method stub
    return 0;
}

如果你尝试了,但遇到了问题,那么你可以问一个问题。

 类似资料:
  • 考虑一下Robert Sedgewick在他的网站上的声明: 我非常困惑,当键大于根时会发生什么,尤其是当他说:“但只有当右子树中有一个键小于或等于键时”。我想他的意思是,如果键小于根,那么键肯定在左子树中。另一方面,如果密钥更大,则密钥“可能”在正确的子树中,因此也可能在正确的子树上找不到密钥。根据他的floor()方法: 他确实检查了右子树,但没有检查左子树。但我完全不能想出一个例子,其中键大

  • 主要内容:什么是二叉排序树?,使用二叉排序树查找关键字,二叉排序树中插入关键字,二叉排序树中删除关键字,总结前几节介绍的都是有关静态 查找表的相关知识,从本节开始介绍另外一种查找表—— 动态查找表。 动态查找表中做查找操作时,若查找成功可以对其进行删除;如果查找失败,即表中无该关键字,可以将该关键字插入到表中。 动态查找表的表示方式有多种,本节介绍一种使用树结构表示动态查找表的实现方法—— 二叉排序树(又称为 “二叉查找树”)。 什么是二叉排序树? 二叉排序树要么是空 二叉树,要么具有如下特点:

  • 我正在努力实现二叉搜索树。完成实现所需的功能之一是重新平衡功能。 根据规范,该功能的工作方式如下: rebalance() 方法应创建一个平衡树,从而将偏度降低为零。平衡树是指在整个树中,左子树和右子树的大小相差不超过1(即,每个子树也是平衡的)。 为了平衡树,rebalance() 方法应反复将根值移动到较小的子树,并将最小/最大值从较大的子树移动到根,直到树平衡。然后,它应该以递归方式平衡两个

  • 本文向大家介绍python实现二叉查找树实例代码,包括了python实现二叉查找树实例代码的使用技巧和注意事项,需要的朋友参考一下 本文研究的主要是python实现二叉查找树的相关内容,具体介绍及实现如下。 1. 二叉查找树的定义: 左子树不为空的时候,左子树的结点值小于根节点,右子树不为空时,右子树的结点值大于根节点,左右子树分别为二叉查找树 2. 二叉查找树的最左边的结点即为最小值,要查找最小

  • 我们已经看到了两种不同的方法来获取集合中的键值对。回想一下,这些集合实现了 map 抽象数据类型。我们讨论的 map ADT 的两个实现是在列表和哈希表上的二分搜索。在本节中,我们将研究二叉查找树作为从键映射到值的另一种方法。 在这种情况下,我们对树中项的确切位置不感兴趣,但我们有兴趣使用二叉树结构来提供高效的搜索。

  • 我正在尝试用java实现二叉树,下面是我的代码: 我无法在我的树中插入新节点,root的值不会改变 当我调用newnode函数时,我得到了我的Root Node的正确值,但在main函数中,它给了我空点异常 为什么root的值没有更新