/**
 * A binary search tree on Strings.
 * 
 * @author Paul Chew
 * 
 * Created September 2005.
 */
public class BST {
    
    private TreeNode root;    // The root of the BST
    public static BST tree;   // An example (created by main())
    
    /**
     * Constructor.
     */
    public BST () {
        root = null;
        return;
    }
    
    /**
     * Insert.
     */
    public void insert (String string) {
        root = insert(string, root);
    }
    
    private static TreeNode insert (String string, TreeNode node) {
        if (node == null) return new TreeNode(string);
        int compare = string.compareTo(node.datum);
        if (compare < 0) node.lchild = insert(string, node.lchild);
        else if (compare > 0) node.rchild = insert(string, node.rchild);
        return node;
    }
    
    /**
     * toString.
     */
    public String toString () {
        return toString("", root);
    }
    
    private static String toString (String prefix, TreeNode node) {
        if (node == null) return "";
        String string = prefix + node.datum.toString();
        if (node.rchild != null) 
            string = toString("    " + prefix, node.rchild) + "\n" + string;
        if (node.lchild != null)
            string = string + "\n" + toString("    " + prefix, node.lchild);
        return string;
    }
    
    /**
     * Preorder
     */
    public void preorder () {
      preorder(root); System.out.println();
    }
    
    private static void preorder (TreeNode node) {
      if (node == null) return;
      System.out.print(node.datum + " ");
      preorder(node.lchild); preorder(node.rchild);
    }
    
    /**
     * Inorder.
     */
    public void inorder () {
      inorder(root); System.out.println();
    }
    
    private static void inorder (TreeNode node) {
      if (node == null) return;
      inorder(node.lchild);
      System.out.print(node.datum + " ");
      inorder(node.rchild);
    }
    
    /**
     * Postorder
     */
    public void postorder () {
      postorder(root); System.out.println();
    }
    
    private static void postorder (TreeNode node) {
      if (node == null) return;
      postorder(node.lchild); postorder(node.rchild);
      System.out.print(node.datum + " ");
    }
    
    /**
     * Test program.
     */
    public static void main (String[] args) {
      BST t = new BST();
      tree = t;
      t.insert("jan");
      t.insert("feb");
      t.insert("mar");
      t.insert("apr");
      t.insert("may");
      t.insert("jun");
      t.insert("jul");
      t.insert("aug");
      t.insert("sep");
      t.insert("oct");
      t.insert("nov");
      t.insert("dec");
      System.out.println(t);
    }
}

/**
 * TreeNode.
 */
class TreeNode {
    
    String datum;                // Data for a node
    TreeNode lchild, rchild;     // Left and right children.
    
    /**
     * Constructor.
     */
    public TreeNode (String datum) {
        this.datum = datum;
        lchild = null; rchild = null;
    }
}
