创建表达式树

时间:2016-10-23 18:39:16

标签: java tree expression binary-tree expression-trees

我想创建一个表达式树,以便我可以使用树的属性对其进行评估。但是,我真的不知道从哪里开始创建表达式树。更具体地说,我很难弄清楚如何在树中使用两种类型的变量:

  • 双倍(数字)
  • char(对于运营商)

我有这个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());
}
}

非常感谢任何对此的帮助,谢谢。

2 个答案:

答案 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取决于你想要使用树的内容。