我想创建一个表达式树,以便我可以使用树的属性对其进行评估。但是,我真的不知道从哪里开始创建表达式树。更具体地说,我很难弄清楚如何在树中使用两种类型的变量:
我有这个LinkedBinaryTree类:
public class LinkedBinaryTree<E> extends AbstractBinaryTree<E>{
protected static class Node<E> implements Position<E> {
private E element; // an element stored at this node
private Node<E> parent; // a reference to the parent node (if any)
private Node<E> left; // a reference to the left child (if any)
private Node<E> right; // a reference to the right child (if any)
public Node(E e, Node<E> above, Node<E> leftChild, Node<E> rightChild) {
element = e;
parent = above;
left = leftChild;
right = rightChild;
}
// accessor methods
public E getElement( ) { return element; }
public Node<E> getParent( ) { return parent; }
public Node<E> getLeft( ) { return left; }
public Node<E> getRight( ) { return right; }
// update methods
public void setElement(E e) { element = e; }
public void setParent(Node<E> parentNode) { parent = parentNode; }
public void setLeft(Node<E> leftChild) { left = leftChild; }
public void setRight(Node<E> rightChild) { right = rightChild; }
} //----------- end of nested Node class -----------
protected Node<E> createNode(E e, Node<E> parent,
Node<E> left, Node<E> right) {
return new Node<E>(e, parent, left, right);
}
// LinkedBinaryTree instance variables
protected Node<E> root = null; // root of the tree
private int size = 0; // number of nodes in the tree
// constructor
public LinkedBinaryTree( ) { } // constructs an empty binary tree
// nonpublic utility
protected Node<E> validate(Position<E> p) throws IllegalArgumentException {
if (!(p instanceof Node))
throw new IllegalArgumentException("Not valid position type");
Node<E> node = (Node<E>) p; // safe cast
if (node.getParent( ) == node) // our convention for defunct node
throw new IllegalArgumentException("p is no longer in the tree");
return node;
}
// accessor methods (not already implemented in AbstractBinaryTree)
public int size( ) {
return size;
}
public Position<E> root( ) {
return root;
}
public Position<E> parent(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getParent( );
}
public Position<E> left(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getLeft( );
}
public Position<E> right(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
return node.getRight( );
}
public Position<E> addRoot(E e) throws IllegalStateException {
if (!isEmpty( )) throw new IllegalStateException("Tree is not empty");
root = createNode(e, null, null, null);
size = 1;
return root;
}
public Position<E> addLeft(Position<E> p, E e)
throws IllegalArgumentException {
Node<E> parent = validate(p);
if (parent.getLeft( ) != null)
throw new IllegalArgumentException("p already has a left child");
Node<E> child = createNode(e, parent, null, null);
parent.setLeft(child);
size++;
return child;
}
public Position<E> addRight(Position<E> p, E e)
throws IllegalArgumentException {
Node<E> parent = validate(p);
if (parent.getRight( ) != null)
throw new IllegalArgumentException("p already has a right child");
Node<E> child = createNode(e, parent, null, null);
parent.setRight(child);
size++;
return child;
}
public E set(Position<E> p, E e) throws IllegalArgumentException {
Node<E> node = validate(p);
E temp = node.getElement( );
node.setElement(e);
return temp;
}
public void attach(Position<E> p, LinkedBinaryTree<E> t1,
LinkedBinaryTree<E> t2) throws IllegalArgumentException {
Node<E> node = validate(p);
if (isInternal(p)) throw new IllegalArgumentException("p must be a leaf");
size += t1.size( ) + t2.size( );
if (!t1.isEmpty( )) { // attach t1 as left subtree of node
t1.root.setParent(node);
node.setLeft(t1.root);
t1.root = null;
t1.size = 0;
}
if (!t2.isEmpty( )) { // attach t2 as right subtree of node
t2.root.setParent(node);
node.setRight(t2.root);
t2.root = null;
t2.size = 0;
}
}
public E remove(Position<E> p) throws IllegalArgumentException {
Node<E> node = validate(p);
if (numChildren(p) == 2)
throw new IllegalArgumentException("p has two children");
Node<E> child = (node.getLeft( ) != null ? node.getLeft( ) : node.getRight( ) );
if (child != null)
child.setParent(node.getParent( )); // child’s grandparent becomes its parent
if (node == root)
root = child; // child becomes root
else {
Node<E> parent = node.getParent( );
if (node == parent.getLeft( ))
parent.setLeft(child);
else
parent.setRight(child);
}
size--;
E temp = node.getElement( );
node.setElement(null); // help garbage collection
node.setLeft(null);
node.setRight(null);
node.setParent(node); // our convention for defunct node
return temp;
}
public String toString(){
String treeString = "(";
if(root != null){
treeString += nodeString(root);
}
return treeString+")";
}
private String nodeString(Node<E> node){
String str = nodeToString(node);
if(node.getLeft()!=null){
str += "("+ nodeString(node.getLeft()) + ")";
}
if(node.getRight()!=null){
str += "("+ nodeString(node.getRight()) + ")";
}
return str;
}
private String nodeToString(Node<E> node){
return "" + node.getElement();
}
public static void main(String[] args) {
LinkedBinaryTree<Integer> tree = new LinkedBinaryTree<Integer>();
Position<Integer> p;
Position<Integer> p1;
Position<Integer> p2;
p = tree.addRoot(5);
p1 = tree.addLeft(p, 3);
p2 = tree.addRight(p, 7);
tree.addLeft(p1, 1);
tree.addRight(p1, 4);
tree.addLeft(p2, 6);
tree.addRight(p2, 9);
System.out.println(tree.toString());
}
}
非常感谢任何对此的帮助,谢谢。
答案 0 :(得分:0)
您的问题是您在树类中的所有位置都使用相同的泛型类型E.鉴于您希望在同一棵树中拥有不同的类型的节点,这根本没有意义。
或者从另一个角度来看:你的问题是,不能有任何 E 适用于Character和Double!
不幸的是,这意味着您可能需要重新编写代码的大部分内容。 如何这样做超出了我现在所能提供的范围,但有很多起点,即使在这个有帮助的网站上,如this,或{{3}上的一些片段}或geeksforgeeks。
答案 1 :(得分:0)
您可以使用String树并将字符和双精度保存为字符串。但是我自己不喜欢这个解决方案,因为无论你在哪里使用它都必须将String转换回双打/字符,你必须始终发现它是一个号码或操作员。
我会创建一个类Expression,而Tree包含Expression LinkedBinaryTree<Expression>
的对象。然后你可以让类继承Expression。您可以为数字class NumberExpression extends Expression
和类class OperatorExpression extends Expression
创建一个类。 foolowup取决于你想要使用树的内容。