//
// BinTree class
//
// this class implements a binary tree
//
// the tree is unbounded. fields are
// info: the value stored in the node (generic type)
// left: pointer to the left subtree
// right: pointer to the right subtree
// parent: pointer to the parent
// preOrderQueue: queue of nodes for preorder traversal
// left, right, and parent are public to allow the client // code to manipulate the tree as needed
//
// methods:
// constructor to create empty tree
// constructor to create tree with one node
// constructor to create tree given the root value, and
// pointers to the left and right subtrees
// get and set methods for the info field
// isEmpty
// attachLeft: if there is no left child, attach the given tree as
// the new left child; otherwisethrowTreeViolationException
// attachRight: if there is no right child, attach the given tree as the // new right child; otherwise throw TreeViolationException
// detachLeft: detach and return the left child
// detachRight: detach and return the right child
// root: return the root of the tree
public class BinTree<T> implements BinTreeInterface<T> {
protected T info;
public BinTree<T> left;
public BinTree<T> right;
public BinTree<T> parent;
private LinkedUnbndQueue<T> preOrderQueue;
// create an empty tree
public BinTree() {
info = null;
left = null;
right = null;
parent = null;
}
// create a tree with one node
public BinTree(T item) {
info = item;
right = null; //idk
left = null; //idk
}
// create a tree where the root contains item
// link the left and right subtrees to the root
// don't forget to set the parent pointers
public BinTree(T item, BinTree<T> ltree, BinTree<T> rtree) {
info = item;
right = rtree;
left = ltree;
ltree = null;
rtree = null;
}
// return the info field
public T getInfo() {
return info;
}
// set the info field
public void setInfo(T newitem) {
info = newitem;
}
// attach the parm as the left child of the current node
// throw TreeViolationException if the current node already has a left child
public void attachLeft(BinTree<T> tree) {
if (this.left != null)
throw new TreeViolationException("Current node already has a left child");
else
this.left = tree;
}
// attach the parm as the right child of the current node
// throw TreeViolationException if the current node already has a right child
public void attachRight(BinTree<T> tree) {
if (this.right != null)
throw new TreeViolationException("Current node already has a right child");
else
this.right = tree;
}
// detach the left child and return it
public BinTree<T> detachLeft() {
return this.left;
}
// detach the right child and return it
public BinTree<T> detachRight() {
return this.right;
}
我认为我的BinTree方法错了。我不明白我在哪里弄错了。
public BinTree<T> root() {
if (this.parent == null)
return this;
else
return this.root();
/// return parent;
}
// Initializes preOrderQueue with tree elements in preOrder order.
public void preOrder(BinTree<T> tree) {
if (tree != null) {
preOrderQueue.enqueue(tree.getInfo());
preOrder(tree.left);
preOrder(tree.right);
}
}
// calls preorder to create queue of nodes in the tree
public void reset() {
preOrderQueue = new LinkedUnbndQueue<T>();
preOrder(this);
}
// removes and returns the next node in the preorder queue
// returns null if the queue is empty
public T getNext() {
if (preOrderQueue.isEmpty())
return null;
else
return preOrderQueue.dequeue();
}
}
这是我的驱动程序代码。 //当我编译fr预订时,它只打印出75及以下的bcz当前节点是75.为什么它不能遍历25和50?
public class useTree {
public static void main(String[] args) {
Integer num;
BinTree<Integer> mytree = new BinTree<Integer>(25);
BinTree<Integer> subtree = new BinTree<Integer>(50);
mytree.attachLeft(subtree);
subtree = new BinTree<Integer>(75);
mytree.attachRight(subtree);
// subtree = new BinTree<Integer>(10);
// mytree.attachRight(subtree);
// 25
// / \
// 50 75
subtree = new BinTree<Integer>(10);
subtree.attachRight(new BinTree<Integer>(100));
subtree.attachLeft(new BinTree<Integer>(200));
mytree = mytree.right;
mytree.attachLeft(subtree);
// 25
// / \
// 50 75
// /
// 10
// / \
// 200 100
mytree = mytree.root();
System.out.println("\npreorder traversal:");
mytree.reset();
num = mytree.getNext();
while (num != null) {
System.out.println(num);
num = mytree.getNext();
}
}
}
答案 0 :(得分:0)
public BinTree root() {
if (parent == null) return null;
BinTree tmp = parent;
while (tmp.parent != null) {
tmp = tmp.parent;
}
return tmp;
}
您应该创建一个单独的类命名BinNode
或其他类。树和节点是分开的东西,你创建的类令人困惑,没有意义。
,您没有在任何地方分配parent
变量。
public void attachRight(BinTree<T> tree) {
if (this.right != null)
throw new TreeViolationException("Current node already has a right child");
else {
this.right = tree;
tree.parent = this;
}
}
适当地分配子分支的父分支。而且,你的分离方法也是错误的。您只是返回右/左分支,但您应首先分离 / 删除。
BinTree branch = this.right; // or left
this.right = null;
return branch;
答案 1 :(得分:0)
public BinTree root() {
if (this.parent == null)
return this;
else
return this.root();
/// return parent;
}
应该是:
public BinTree root() {
if (this.parent == null)
return this;
else
return this.parent.root();
}
这使用递归,这不是最优的,但它至少是正确的。
此外:
private LinkedUnbndQueue<T> preOrderQueue;
树的每个节点都有自己的队列?那不对。如果您确实要生成队列,请将队列对象传递给相关方法。而且,为什么preOrder
方法需要树参数 - 它不是静态方法; &#34;这&#34;作为一个隐含的论点。
public void preOrder(LinkedUnbndQueue<T> preOrderQueue) {
preOrderQueue.enqueue(this.getInfo());
if (left != null) left.preOrder(preOrderQueue);
if (right != null) right.preOrder(preOrderQueue);
}
此外,attachLeft
和attachRight
方法需要设置附加子树的parent
字段。
更一般地说,您的BinTree
既是节点又是树。这可以工作,但有些操作在每个节点的基础上确实没有意义(特别是你定义的自定义迭代应该被移出,因为正如我所指出的,它并没有多大意义每个节点有一个队列。)
坦率地说,这段代码存在足够的问题,需要更好的方法来开发实践。考虑学习使用调试器。