我正在尝试将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);
}
}
请按照老师的要求尝试实施以下两种方法:
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的值没有更新