BinTree.java :  » Parser » SJPT » ro » infoiasi » donald » compiler » simple » Java Open Source

Java Open Source » Parser » SJPT 
SJPT » ro » infoiasi » donald » compiler » simple » BinTree.java
package ro.infoiasi.donald.compiler.simple;

import java.util.*;

/** A binary tree of objects */
public class BinTree {
  private BinTreeNodeP root;

  /** A node in a binary tree */
  private class BinTreeNodeP implements BinTreeNode {
    private Object obj;
    private BinTreeNodeP parent;
    private BinTreeNodeP left;
    private BinTreeNodeP right;
    private int weight = 1;

    BinTreeNodeP(Object obj) {
      this.obj = obj;
    }

    public void put(Object obj) {
      this.obj = obj;
    }
    public Object get() {
      return obj;
    }

    public BinTreeNode parent() {
      return parent;
    }
    public BinTreeNode left() {
      return left;
    }
    public BinTreeNode right() {
      return right;
    }
    
    public String toString() {
      return "["+obj+"]";
    }
  }

  private abstract class BinTreeIterator implements Iterator {
    protected BinTreeNodeP p = root;
    protected BinTreeNodeP q = null;
    protected int visited = 0;

    /** Returns true if the iteration has more elements. */
    public boolean hasNext() {
      if (visited<size()) {
        return true;
      } else {
        return false;
      }
    }

    /** Returns the next element in the iteration. */
    public abstract Object next();

    /** A node of the tree cannot be removed unless it is a leaf */
    public void remove() throws UnsupportedOperationException {
      throw new UnsupportedOperationException();
    }
  }

  /** Iterates the nodes of the tree in pre-order (root-left-right) */
  private class PreIterator extends BinTreeIterator {
    /** Returns the next element in the iteration. */
    public Object next() throws NoSuchElementException {
      if (p == null || (p == root && q != null)) {
        throw new NoSuchElementException();
      } else {
        boolean foundNext = false;
        do {
          if (q == p.parent) {
            q = p;
            if (p.left != null) 
              p = p.left;
            else {
              if (p.right != null) 
                p = p.right;
              else {
                p = p.parent;
              }
            }
            foundNext = true;
          } else if (q == p.left) {
            q = p;
            if (p.right != null)
              p = p.right;
            else {
              p = p.parent;
            }
          } else {
            q = p;
            p = p.parent;
          }
        } while (p != null && !foundNext);
        //System.out.println("p:"+p+" q:"+q);
        visited++;
        return q;
      }
    }
  }

  /** Iterates the nodes of the tree in in-order (left-root-right) */
  private class InIterator extends BinTreeIterator {
    /** Returns the next element in the iteration. */
    public Object next() throws NoSuchElementException {
      if (p == null) {
        throw new NoSuchElementException();
      } else {
        boolean foundNext = false;
        do {
          if (q == p.parent) {
            q = p;
            if (p.left != null) 
              p = p.left;
            else {
              if (p.right != null) 
                p = p.right;
              else {
                p = p.parent;
              }
              foundNext = true;
            }
          } else if (q == p.left) {
            q = p;
            if (p.right != null)
              p = p.right;
            else {
              p = p.parent;
            }
            foundNext = true;
          } else {
            q = p;
            p = p.parent;
          }
        } while (p != null && !foundNext);
        visited++;
        return q;
      }
    }
  }

  /** Iterates the nodes of the tree in post-order (left-right-root) */
  private class PostIterator extends BinTreeIterator {
    /** Returns the next element in the iteration. */
    public Object next() throws NoSuchElementException {
      if (p == null) {
        throw new NoSuchElementException();
      } else {
        boolean foundNext = false;
        while (p != null && !foundNext) {
          if (q == p.parent) {
            q = p;
            if (p.left != null) 
              p = p.left;
            else {
              if (p.right != null) 
                p = p.right;
              else {
                p = p.parent;
                foundNext = true;
              }
            }
          } else if (q == p.left) {
            q = p;
            if (p.right != null)
              p = p.right;
            else {
              p = p.parent;
              foundNext = true;
            }
          } else {
            q = p;
            p = p.parent;
            foundNext = true;
          }
        }
        visited++;
        return q;
      }
    }
  }

  /** Returns the root of the tree. */
  public BinTreeNode root() {
    return root;
  }
  
  /** Returns the number of nodes in the tree. */
  public int size() {
    return getWeight(root);
  }

  /** Returns the number of nodes in the subtree of the specified node */ 
  private int getWeight(BinTreeNodeP node) {
    if (node != null) {
      return node.weight;
    } else {
      return 0;
    }
  }

  /** Fixes the weights of the given node and of all
  the nodes all the way to the root of the tree */
  private void fixWeight(BinTreeNodeP node, int i) {
    if (i != 0) {
      while (node != null) {
        node.weight += i;
        node = node.parent;
      }
    }
  }
  
  /** Adds the given object as the root of the tree.
  If the tree already had a root the link to that node
  (and possibly many others) is lost.*/
  public BinTreeNode addRoot(Object obj) {
    root = new BinTreeNodeP(obj);
    return root;
  }

  /** Adds the given subTree as the root of the tree. */
  public void addRootSubTree(BinTree subTree) {
    subTree.root.parent = null;
    root = subTree.root;
  }

  /** Adds the given object as a left child of the specified parent.
  If the parent already had a left child the link to that node
  (and possibly many others) is lost.*/
  public BinTreeNode addLeftChild(Object obj, BinTreeNode parentNode) {
    BinTreeNodeP node = new BinTreeNodeP(obj);
    BinTreeNodeP p = (BinTreeNodeP)parentNode;
    fixWeight(p, 1-getWeight(p.left));
    node.parent = p;
    p.left = node;
    return node;
  }

  /** Adds the given tree as the left subtree of the specified parent.
  If the parent already had a left child the link to that node
  (and possibly many others) is lost.*/
  public void addLeftSubTree(BinTree subTree, BinTreeNode parentNode) {
    BinTreeNodeP p = (BinTreeNodeP)parentNode;
    fixWeight(p, subTree.size()-getWeight(p.left));
    subTree.root.parent = p;
    p.left = subTree.root;
  }
  
  /** Adds the given object as a right child of the specified parent.
  If the parent already had a right child the link to that node
  (and possibly many others) is lost.*/
  public BinTreeNode addRightChild(Object obj, BinTreeNode parentNode) {
    BinTreeNodeP node = new BinTreeNodeP(obj);
    BinTreeNodeP p = (BinTreeNodeP)parentNode;
    fixWeight(p, 1-getWeight(p.right));
    node.parent = p;
    p.right = node;
    return node;
  }
  
  /** Adds the given tree as the right subtree of the specified parent.
  If the parent already had a right child the link to that node
  (and possibly many others) is lost.*/
  public void addRightSubTree(BinTree subTree, BinTreeNode parentNode) {
    BinTreeNodeP p = (BinTreeNodeP)parentNode;
    fixWeight(p, subTree.size()-getWeight(p.right));
    subTree.root.parent = p;
    p.right = subTree.root;
  }
  
  /** Removes the specified node and all its children from the tree. */
  public void removeNode(BinTreeNode node) {
    BinTreeNodeP p = (BinTreeNodeP)node;
    if (p == root) {
      root = null;
    } else {
      fixWeight(p.parent, -getWeight(p));
      if (p.parent.left == p) {
        p.parent.left = null;
      } else {
        p.parent.right = null;
      }
      p.parent = null;
    }
  }

  /** Returns an Iteratator that over the nodes of this
  tree in pre-order sequence (root-left-right). */
  public Iterator preIterator() {
    return new PreIterator();
  }

  /** Returns an Iteratator that over the nodes of this
  tree in in-order sequence (left-root-right). */
  public Iterator inIterator() {
    return new InIterator();
  }

  /** Returns an Iteratator that over the nodes of this
  tree in post-order sequence (left-right-root) */
  public Iterator postIterator() {
    return new PostIterator();
  }
  
  /** Returns true if the tree has no nodes. */
  public boolean IsEmpty() {
    return root == null;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.