Search Tree : Dictionary « Collections Data Structure « Java

Home
Java
1.2D Graphics GUI
2.3D
3.Advanced Graphics
4.Ant
5.Apache Common
6.Chart
7.Class
8.Collections Data Structure
9.Data Type
10.Database SQL JDBC
11.Design Pattern
12.Development Class
13.EJB3
14.Email
15.Event
16.File Input Output
17.Game
18.Generics
19.GWT
20.Hibernate
21.I18N
22.J2EE
23.J2ME
24.JDK 6
25.JNDI LDAP
26.JPA
27.JSP
28.JSTL
29.Language Basics
30.Network Protocol
31.PDF RTF
32.Reflection
33.Regular Expressions
34.Scripting
35.Security
36.Servlets
37.Spring
38.Swing Components
39.Swing JFC
40.SWT JFace Eclipse
41.Threads
42.Tiny Application
43.Velocity
44.Web Services SOA
45.XML
Java » Collections Data Structure » DictionaryScreenshots 
Search Tree
     
//package termproject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * (2,4) Search Tree
 *
 * Description: An ADT for a (2,4) Search Tree as described on page 451 of
 * the Data Structures and Algorithms in Java textbook.
 *
 * Date Created: December, 2008
 @author Alex Laird, Wes Perrien
 @version 1.0
 */
public class TwoFourTree implements Dictionary
{
  private Comparator treeComp;
  private int size = 0;
  private TFNode treeRoot = null;

  /**
   * Default constructor which assigns the comparator for the tree.
   
   @param comp Comparator the comparator to be assigned
   */
  public TwoFourTree(Comparator comp)
  {
    treeComp = comp;
  }

  /**
   * Returns the current size of the tree.
   
   @return int the current size of the tree.
   */
  public int size()
  {
    return size;
  }

  /**
   * Returns true if the tree is empty, otherwise false.
   
   @return boolean whether the tree is empty or not
   */
  public boolean isEmpty()
  {
    return (size == 0);
  }

  /**
   * Returns a pointer to the root node of the tree.
   
   @return TFNode the root node
   */
  public TFNode root()
  {
      return treeRoot;
  }

  /**
   * Finds an the first element in the tree with the specified key.
   
   @param key Object the key that is to be found in the tree
   @return Object the Item that contains the specified key
   @throws ElementNotFoundException if the key is not found in the tree
   */
  public Object findElement (Object keythrows ElementNotFoundException
  {
      TFNode node = firstGreaterOrEqualNode(key, root());
      int itemIndex = firstGreaterOrEqualItem(key, node);
      
      if(itemIndex == -1)
          throw new ElementNotFoundException();

      if(treeComp.isEqual(key, ((Itemnode.getItem(itemIndex)).key()))
          return node.getItem(itemIndex);
      else
          throw new ElementNotFoundException();
  }

  /**
   * Inserts an Item with the specified key and element into the tree at it's
   * proper location. This function determines the in order successor based on
   * the specified key to find the proper location.
   
   @param key Object the key to be used for the inserted Item
   @param element Object the element to be used for the inserted Item
   */
  public void insertElement (Object key, Object element)
  {
      Item newItem = new Item(key, element);

      // if this is the first element, make a root node
      if(size() == 0)
      {
          treeRoot = new TFNode();
          treeRoot.addItem(0, newItem);

          size++;

          return;
      }

      // find the node that contains the first greater or equal item
      TFNode greatest = findInsertionPointer(newItem.key(), root());

      if(greatest != null)
      {
          // find greatest or equal item within node
          int index = firstGreaterOrEqualItem(newItem.key(), greatest);

          // if a greater or equal item was not found in node, add at end
          if(index == -1)
              index = greatest.numItems();

          // insert item at proper location
          greatest.insertItem(index, newItem);
      }
      // if a greater or equal node was not found, insert at root
      else
      {
          greatest = treeRoot;

          // walks to the far right child
          while(greatest.getChild(greatest.numItems()) != null)
              greatest = greatest.getChild(greatest.numItems());

          greatest.addItem(greatest.numItems(), newItem);
      }

      // incremet tree size
      size++;

      // if the insert caused a node to be greater than the max allowed size
      // a node split is required
      if(greatest.numItems() == greatest.maxItems() 1)
      {
          nodePop(greatest);
      }
  }

  /**
   * Removes the first element from the tree that matches the specified key.
   
   @param key Object the key to be removed by the first found element
   @return Object the Item that contains the specified key
   @throws ElementNotFoundException if the key is not found in the tree
   */
  public Object removeElement (Object keythrows ElementNotFoundException
  {
      // ensure that the element is in the tree and find it
      findElement(key);
      TFNode node = firstGreaterOrEqualNode(key, root());
      TFNode inOrderSuccessor = null;
      Object element;
      // find the index of the element within the node
      int location = firstGreaterOrEqualItem(key, node);

      // if the node is internal
      if(node.getChild(location + 1!= null)
      {
          inOrderSuccessor = node.getChild(location + 1);
          
          // find the in order successor
          while(inOrderSuccessor.getChild(0!= null)
              inOrderSuccessor = inOrderSuccessor.getChild(0);

          node.insertItem(location, inOrderSuccessor.removeItem(0));
          
          location++;
      }

      // remove the item from the tree
      element = node.removeItem(location);

      // rebalance the tree if the node has become empty
      if(node.numItems() == 0
         && node != root())
          rebalance(node);
      
      // rebalance tree if in order successor has become empty
      if(inOrderSuccessor != null
         && inOrderSuccessor.numItems() == 0)
          rebalance(inOrderSuccessor);

      return element;
  }

  /**
   * Determines whether the specified node has a left sibling or not. If it does
   * have a left sibling, this method returns the index to the left sibling.
   
   @param node TFNode the node to be checked for a left sibling
   @return int -1 if there is no left sibling, otherwise the index of the left sibling
   */
  protected int hasLeftSibling(TFNode node)
  {
      int childIndex;

      // find the index in the parent of the current node
      for(childIndex = 0; childIndex < 4; childIndex++)
      {
          if (node.getParent().getChild(childIndex== node)
              break;
      }

      if(childIndex != 0
         && node.getParent().getChild(childIndex - 1!= null)
         // return the index of the left sibling
         return childIndex - 1;
      else
        // no left sibling exists
        return -1;
  }

  /**
   * Determines whether the specified node has a right sibling or not. If it does
   * have a right sibling, this method returns the index to the right sibling.
   
   @param node TFNode the node to be checked for a right sibling
   @return int -1 if there is no right sibling, otherwise the index of the right sibling
   */
  protected int hasRightSibling(TFNode node)
  {
      int childIndex;

      // find the index in the parent of the current node
      for(childIndex = 0; childIndex < 4; childIndex++)
      {
          if (node.getParent().getChild(childIndex== node)
              break;
      }

      if(childIndex != 3
         && node.getParent().getChild(childIndex + 1!= null)
        // return the index of the right sibling
        return childIndex + 1;
      else
        // no right sibling exists
        return -1;
  }

  /**
   * This method will rebalance if needed, usually directly following a remove.
   
   @param node TFNode the node to be the starting point for rebalance
   */
  protected void rebalance(TFNode node)
  {
      // check siblings
      int leftSibIndex = hasLeftSibling(node);
      int rightSibIndex = hasRightSibling(node);

      TFNode leftSib = null;
      TFNode rightSib = null;
      TFNode parent = node.getParent();
      TFNode newNode = null;
      
      if(leftSibIndex != -1)
      {
          // get the left sibling
        leftSib = parent.getChild(leftSibIndex);  
      }
      if(rightSibIndex != -1)
      {
          // get the right sibling
        rightSib = parent.getChild(rightSibIndex);
      }
      
      // transfer from left sibling
      if(leftSibIndex != -1
         && leftSib.numItems() 1)
      {
        // insert parent into index 0
        node.insertItem(0, parent.getItem(leftSibIndex));
        
        // make left sibling's most right child the first child here
        node.setChild(0, leftSib.getChild(leftSib.numItems()));
          
        if(node.getChild(0!= null)
          node.getChild(0).setParent(node);
        
          // store the last pointer reference
          TFNode pointer = leftSib.getChild(leftSib.numItems() 1);
          
        // make left sibling's greatest item the new parent
        parent.replaceItem(leftSibIndex, leftSib.removeItem(leftSib.numItems() 1));
          
          // reset the last pointer
          leftSib.setChild(leftSib.numItems(), pointer);
      }
      // transfer from right sibling
      else if(rightSibIndex != -1
            && rightSib.numItems() 1)
      {
        // insert parent into index 0
        node.insertItem(0, parent.getItem(rightSibIndex - 1));
        
        // make right sibling's first child the last child here
        node.setChild(0, rightSib.getChild(0));
        if(node.getChild(0!= null)
                node.getChild(0).setParent(node);
        
          // store the third last pointer reference
          TFNode pointer = rightSib.getChild(0);
          
        // make right sibling's first item the new parent
        parent.replaceItem(rightSibIndex - 1, rightSib.removeItem(0));
          
          // reset the last pointer
          rightSib.setChild(rightSib.numItems(), pointer);
      }
      // neither sibling has enough elements
      else
      {
        // left fusion
          if(leftSib != null
             && leftSib.numItems() == 1)
          {
              // store nodes pointer
              TFNode pointer = node.getChild(0);
              
              if(treeComp.isLessThan(((ItemleftSib.getItem(0)).key()((Itemparent.getItem(leftSibIndex)).key()))
            leftSib.addItem(1, parent.removeItem(leftSibIndex));
              else
            leftSib.insertItem(0, parent.removeItem(leftSibIndex));
            
              // reset the last pointer
              leftSib.setChild(leftSib.numItems(), pointer);
              
              if(pointer != null)
                pointer.setParent(leftSib);
              
              parent.setChild(leftSibIndex, leftSib);
              newNode = leftSib;
          }
          // right fusion
          else
          {
              // store the nodes pointer
              TFNode pointer = node.getChild(rightSib.numItems());
              
              if(treeComp.isLessThan(((ItemrightSib.getItem(0)).key()((Itemparent.getItem(rightSibIndex - 1)).key()))
                   rightSib.addItem(1, node.getParent().removeItem(rightSibIndex - 1));
              else
                   rightSib.insertItem(0, node.getParent().removeItem(rightSibIndex - 1));
            
              // reset the first pointer
              rightSib.setChild(0, pointer);
              
              if(pointer != null)
                  pointer.setParent(rightSib);
              
              parent.setChild(rightSibIndex - 1, rightSib);
              newNode = rightSib;
          }
      }
      
      // rebalance parent recursively if it has zero items and is not he parent
      if(parent.numItems() == 0)
      {
          if(parent != root())
             rebalance(parent);
          else
          {
             treeRoot = newNode;
             newNode.setParent(null);
             
             size--;
          }
      }
      
      node = null;
  }

  /**
   * Searches the tree until it finds a node with an item that is greater than
   * or equal to the specified key.
   
   @param key Object the key to be compared against
   @param node TFNode the node to be the starting point, usually the root
   @return TFNode the node that holds the first greater or equal item
   */
  protected TFNode firstGreaterOrEqualNode(Object key, TFNode start)
  {
      // recursive exit condition
      if(start == null)
          return null;
      
      int index = firstGreaterOrEqualItem(key, start);
      
      if(index == -1)
      {
          index = start.numItems();
          return firstGreaterOrEqualNode(key, start.getChild(index));
      }
      
      if(treeComp.isLessThan(key, ((Itemstart.getItem(index)).key()))
         return firstGreaterOrEqualNode(key, start.getChild(index));
      else if(treeComp.isGreaterThan(key, ((Itemstart.getItem(index)).key()))
              return firstGreaterOrEqualNode(key, start.getChild(index + 1));
      else
          return start;
  }
  
  /**
   * Searches the node until it finds a node that is greater than or equal to
   * the specified key.
   
   @param key Object the key to be compared against
   @param node TFNode the node to be searched
   @return int the index of the first greater than or equal item
   */
  protected int firstGreaterOrEqualItem(Object key, TFNode nodethrows ElementNotFoundException
  {
      if(node == null)
          throw new ElementNotFoundException();
      
      // find first greater or equal item within the node
      for(int i = 0; i < node.numItems(); i++)
      {
          if (treeComp.isGreaterThanOrEqualTo(((Itemnode.getItem(i)).key(), key))
              return i;
      }

      // no greater or equal item was found
      return -1;
  }

  /**
   * Searches the tree until it finds a node with an item that is greater than
   * or equal to the specified key.  This is the point at which it will insert
   * the a new node.
   
   @param key Object the key to be compared against
   @param start TFNode the node to be the starting point, usually the root
   @return TFNode the node that holds the first greater or equal item
   */
  protected TFNode findInsertionPointer(Object key, TFNode start)
  {
      // exit condition for recursion
      if(start == null)
          return null;

      int index = firstGreaterOrEqualItem(key, start)

      // if a greater or equal item was not found in node, add at end
      if(index == -1)
          index = start.numItems();

      // continue searching down tree
      TFNode node = findInsertionPointer(key, start.getChild(index));

      if(node == null)
          return start;

      return node;
  }

  /**
   * Pops the third item out of a node and sends it to the parent, thus creating
   * the children nodes off of that parent then. Essentially a node split. Usually
   * called directly after an insert if the insert causes a node to become too full.
   
   @param left TFNode the node to be split
   */
  protected void nodePop(TFNode left)
  {
      TFNode parent;
      TFNode right = new TFNode();
      int index;

      // if no parent exists, we are the root
      if(left.getParent() == null)
      {
          parent = new TFNode();
          treeRoot = parent;

          index = 0;
      }
      else
      {
          parent = left.getParent();
          index = firstGreaterOrEqualItem(((Itemleft.getItem(2)).key(), parent);

          // if a greater or equal item was not found in node, add at end
          if(index == -1)
              index = parent.numItems();
      }

      // insert items in new locations
      parent.insertItem(index, left.getItem(2));
      right.addItem(0, left.getItem(3));

      // set new child pointers
      parent.setChild(index, left);
      parent.setChild(index + 1, right);

      // set parent pointers
      left.setParent(parent);
      right.setParent(parent);

      // conditions if the node has more than three children
      if(left.getChild(3!= null)
      {
          right.setChild(0, left.getChild(3));
          right.getChild(0).setParent(right);
      }
      if(left.getChild(4!= null)
      {
          right.setChild(1, left.getChild(4));
          right.getChild(1).setParent(right);
      }

      // store the third pointer reference
      TFNode pointer = left.getChild(2);

      // remove the two items
      left.removeItem(2);
      left.removeItem(2);

      // reassign the child which was lost in the remove
      left.setChild(2, pointer);

      // check to see if the parent is too full now; call recursion
      if(parent.numItems() == parent.maxItems() 1)
          nodePop(parent);
  }

  /**
   * The main method which the program executes from and which handles all
   * testing and input/output.
   
   @param args String[]
   */
  public static void main(String[] argsthrows IOException
  {
        Comparator myComp = new IntegerComparator();
        TwoFourTree myTree = new TwoFourTree(myComp);
        TwoFourTree firstTree = new TwoFourTree(myComp);
        TwoFourTree secondTree = new TwoFourTree(myComp);
        BufferedReader myReader = new BufferedReader(new InputStreamReader(System.in));
        String input;
        boolean go = true;
    
        while(go == true)
        {
            System.out.print("Format like this:  -a 37 to add a 37 to the tree. -r 37 to remove a 37 from the tree: ");
            input = myReader.readLine();
            
            if(input.substring(02).equals("-a"))
            {
                Integer myInt = new Integer(input.substring(3, input.length()));
                myTree.insertElement(myInt, myInt);
                myTree.printAllElements();
            }
            else if(input.substring(02).equals("-r"))
            {
                Integer myInt = new Integer(input.substring(3, input.length()));
                myTree.removeElement(myInt);
                myTree.printAllElements();
            }
            else
                System.out.print("\nYou're bad!");
            
            System.out.print("\n");
                
        }
        
        /*System.out.println("Loading firstTree with values ...");
        
        Integer firstInt1 = new Integer(20);
        firstTree.insertElement(firstInt1, firstInt1);
        Integer firstInt2 = new Integer(50);
        firstTree.insertElement(firstInt2, firstInt2);
        Integer firstInt3 = new Integer(30);
        firstTree.insertElement(firstInt3, firstInt3);
        Integer firstInt4 = new Integer(40);
        firstTree.insertElement(firstInt4, firstInt4);
        Integer firstInt5 = new Integer(15);
        firstTree.insertElement(firstInt5, firstInt5);
        Integer firstInt6 = new Integer(35);
        firstTree.insertElement(firstInt6, firstInt6);
        Integer firstInt7 = new Integer(55);
        firstTree.insertElement(firstInt7, firstInt7);
        Integer firstInt8 = new Integer(38);
        firstTree.insertElement(firstInt8, firstInt8);
        Integer firstInt9 = new Integer(17);
        firstTree.insertElement(firstInt9, firstInt9);
        Integer firstInt10 = new Integer(37);
        firstTree.insertElement(firstInt10, firstInt10);
        Integer firstInt11 = new Integer(16);
        firstTree.insertElement(firstInt11, firstInt11);
        Integer firstInt12 = new Integer(36);
        firstTree.insertElement(firstInt12, firstInt12);
        Integer firstInt13 = new Integer(15);
        firstTree.insertElement(firstInt13, firstInt13);
        Integer firstInt14 = new Integer(36);
        firstTree.insertElement(firstInt14, firstInt14);
        Integer firstInt15 = new Integer(30);
        firstTree.insertElement(firstInt15, firstInt15);
        Integer firstInt16 = new Integer(34);
        firstTree.insertElement(firstInt16, firstInt16);
        Integer firstInt17 = new Integer(34);
        firstTree.insertElement(firstInt17, firstInt17);
        Integer firstInt18 = new Integer(30);
        firstTree.insertElement(firstInt18, firstInt18);
        Integer firstInt19 = new Integer(30);
        firstTree.insertElement(firstInt18, firstInt18);
       
        System.out.println("firstTree is fully loaded as follows:");
        firstTree.printAllElements();
        System.out.println("Checking parent/child connections ...");
        firstTree.checkTree(firstTree.root());
        System.out.println("All parent/child connections valid.");
        
        System.out.println("\nRemove 30");
        firstTree.removeElement(30);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 30");
        firstTree.removeElement(30);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 30");
        firstTree.removeElement(30);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 30");
        firstTree.removeElement(30);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 15");
        firstTree.removeElement(15);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 55");
        firstTree.removeElement(55);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 35");
        firstTree.removeElement(35);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 38");
        firstTree.removeElement(38);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 40");
        firstTree.removeElement(40);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 36");
        firstTree.removeElement(36);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 17");
        firstTree.removeElement(17);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 34");
        firstTree.removeElement(34);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 34");
        firstTree.removeElement(34);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 36");
        firstTree.removeElement(36);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 20");
        firstTree.removeElement(20);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 37");
        firstTree.removeElement(37);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 16");
        firstTree.removeElement(16);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 50");
        firstTree.removeElement(50);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 15");
        firstTree.removeElement(15);
        System.out.println("Removed successfully. Print new tree:");
        firstTree.printAllElements();
        System.out.println("done");

        System.out.println("\n\nLoading secondTree with values ...");
        
        Integer secondInt1 = new Integer(47);
        secondTree.insertElement(secondInt1, secondInt1);
        Integer secondInt2 = new Integer(83);
        secondTree.insertElement(secondInt2, secondInt2);
        Integer secondInt3 = new Integer(22);
        secondTree.insertElement(secondInt3, secondInt3);
        Integer secondInt4 = new Integer(16);
        secondTree.insertElement(secondInt4, secondInt4);
        Integer secondInt5 = new Integer(49);
        secondTree.insertElement(secondInt5, secondInt5);
        Integer secondInt6 = new Integer(100);
        secondTree.insertElement(secondInt6, secondInt6);
        Integer secondInt7 = new Integer(38);
        secondTree.insertElement(secondInt7, secondInt7);
        Integer secondInt8 = new Integer(3);
        secondTree.insertElement(secondInt8, secondInt8);
        Integer secondInt9 = new Integer(53);
        secondTree.insertElement(secondInt9, secondInt9);
        Integer secondInt10 = new Integer(66);
        secondTree.insertElement(secondInt10, secondInt10);
        Integer secondInt11 = new Integer(19);
        secondTree.insertElement(secondInt11, secondInt11);
        Integer secondInt12 = new Integer(23);
        secondTree.insertElement(secondInt12, secondInt12);
        Integer secondInt13 = new Integer(24);
        secondTree.insertElement(secondInt13, secondInt13);
        Integer secondInt14 = new Integer(88);
        secondTree.insertElement(secondInt14, secondInt14);
        Integer secondInt15 = new Integer(1);
        secondTree.insertElement(secondInt15, secondInt15);
        Integer secondInt16 = new Integer(97);
        secondTree.insertElement(secondInt16, secondInt16);
        Integer secondInt17 = new Integer(94);
        secondTree.insertElement(secondInt17, secondInt17);
        Integer secondInt18 = new Integer(35);
        secondTree.insertElement(secondInt18, secondInt18);
        Integer secondInt19 = new Integer(51);
        secondTree.insertElement(secondInt19, secondInt19);
        
        System.out.println("firstTree is fully loaded as follows:");
        secondTree.printAllElements();
        System.out.println("Checking parent/child connections ...");
        secondTree.checkTree(secondTree.root());
        System.out.println("All parent/child connections valid.");
        
        System.out.println("\nRemove 19");
        secondTree.removeElement(19);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 3");
        secondTree.removeElement(3);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 66");
        secondTree.removeElement(66);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 88");
        secondTree.removeElement(88);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 94");
        secondTree.removeElement(94);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 100");
        secondTree.removeElement(100);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 97");
        secondTree.removeElement(97);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 47");
        secondTree.removeElement(47);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 53");
        secondTree.removeElement(53);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 38");
        secondTree.removeElement(38);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 24");
        secondTree.removeElement(24);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 83");
        secondTree.removeElement(83);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 49");
        secondTree.removeElement(49);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 23");
        secondTree.removeElement(23);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 51");
        secondTree.removeElement(51);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 1");
        secondTree.removeElement(1);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 22");
        secondTree.removeElement(22);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 16");
        secondTree.removeElement(16);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("");
        System.out.println("Remove 35");
        secondTree.removeElement(35);
        System.out.println("Removed successfully. Print new tree:");
        secondTree.printAllElements();
        System.out.println("done");*/
  }

  public void printAllElements() {
    int indent = 0;
    if (root() == null) {
      System.out.println("The tree is empty");
    }
    else {
      printTree(root(), indent);
    }
  }

  public void printTree(TFNode start, int indent) {
    if (start == null) {
      return;
    }
    for (int i = 0; i < indent; i++) {
      System.out.print(" ");
    }
    printTFNode(start);
    indent += 4;
    int numChildren = start.numItems() 1;
    for (int i = 0; i < numChildren; i++) {
      printTree(start.getChild(i), indent);
    }
  }

  public void printTFNode(TFNode node) {
    int numItems = node.numItems();
    for (int i = 0; i < numItems; i++) {
      System.out.print( ( (Itemnode.getItem(i)).element() " ");
    }
    System.out.println();
  }

  // checks if tree is properly hooked up, i.e., children point to parents
  public void checkTree(TFNode start) {
    if (start == null) {
      return;
    }

    if (start.getParent() != null) {
      TFNode parent = start.getParent();
      int childIndex = 0;
      for (childIndex = 0; childIndex <= parent.numItems(); childIndex++) {
        if (parent.getChild(childIndex== start) {
          break;
        }
      }
      // if child wasn't found, print problem
      if (childIndex > parent.numItems()) {
        System.out.println("Child to parent confusion");
        printTFNode(start);
      }
    }

    if (start.getChild(0!= null) {
      for (int childIndex = 0; childIndex <= start.numItems(); childIndex++) {
        if (start.getChild(childIndex).getParent() != start) {
          System.out.println("Parent to child confusion");
          printTFNode(start);
        }
      }
    }

    int numChildren = start.numItems() 1;
    for (int childIndex = 0; childIndex < numChildren; childIndex++) {
      checkTree (start.getChild(childIndex));
    }

  }
}


/**
 * Basic storage element for the 2-4 Tree
 *
 @author Dr. Gallagher
 @version 1.0
 * Created 2 Mar 2001
 * Description: The basic node for a 2-4 tree.  Contains an array of Items,
 * an array of references to children TFNodes, a pointer to a parent TFNode,
 * and a count of how many Items are stored in the node.
 */

class TFNode {

    private static final int MAX_ITEMS = 3;

    private int numItems = 0;
    private TFNode nodeParent;
    private TFNode[] nodeChildren;
    private Object[] nodeItems;

    public TFNode() {
            // make them one bigger than needed, so can handle oversize nodes
            // during inserts
        nodeChildren = new TFNode[MAX_ITEMS+2];
        nodeItems = new Object[MAX_ITEMS+1];
    }

    public int numItems () {
        return numItems;
    }

    public int maxItems() {
        return MAX_ITEMS;
    }

    public TFNode getParent() {
        return nodeParent;
    }
    public void setParent (TFNode parent) {
        nodeParent = parent;
    }
    public Object getItem(int index) {
        if ( (index < 0|| (index > (numItems-1) ) )
            throw new TFNodeException();
        return nodeItems[index];
    }
        // adds, but does not extend array; so it overwrites anything there
    public void addItem (int index, Object data) {
            // always add at end+1; check that you are within array
        if ( (index < 0|| (index > numItems|| (index > MAX_ITEMS) )
            throw new TFNodeException();
        nodeItems[index= data;
        numItems++;
    }
        // this function inserts an item into the node, and adjusts into child
        // pointers to add the proper corresponding pointer
    public void insertItem (int index, Object data) {
        if ( (index < 0|| (index > numItems|| (index > MAX_ITEMS) )
            throw new TFNodeException();
            // adjust Items
        for (int ind=numItems; ind > index; ind--) {
            nodeItems[ind= nodeItems[ind-1];
        }
            // insert new data into hole made
        nodeItems[index= data;
            // adjust children pointers; if inserting into index=1, we make
            // pointers 1 and 2 to point to 1; this is because whoever called
            // this function will fix one of them later; index 0 doesn't change;
            // pointer 3 becomes pointer 2; pointer 4 becomes 3, etc.
        for (int ind=numItems+1; ind > index; ind--) {
            nodeChildren[ind= nodeChildren[ind-1];
        }

        numItems++;
    }

        // this method removes item, and shrinks array
    public Object removeItem (int index) {
        if ( (index < 0|| (index > (numItems-1) ) )
            throw new TFNodeException();
        Object removedItem = nodeItems[index];

        for (int ind=index; ind < numItems-1; ind++) {
            nodeItems[ind= nodeItems[ind+1];
        }
        nodeItems[numItems-1null;
            // fix children pointers also
            // typically, you wouldn't expect to do a removeItem unless
            // children are null, because removal of an item will mess up the
            // pointers; however, here we will simply delete the child to the
            // left of the removed item; i.e., the child with same index
        for (int ind=index; ind < numItems; ind++) {
            nodeChildren[ind= nodeChildren[ind+1];
        }
        nodeChildren[numItemsnull;
        numItems--;
        return removedItem;
    }

        // this method removes item, but does not shrink array
    public Object deleteItem (int index) {
        if ( (index < 0|| (index > (numItems-1) ) )
            throw new TFNodeException();
        Object removedItem = nodeItems[index];
        nodeItems[indexnull;

        numItems--;
        return removedItem;
    }
        // replaces Item at index with newItem, returning the old Item
    public Object replaceItem (int index, Object newItem) {
        if ( (index < 0|| (index > (numItems-1) ) )
            throw new TFNodeException();
        Object returnItem = nodeItems[index];

        nodeItems[index= newItem;
        return returnItem;
    }

    public TFNode getChild (int index) {
        if ( (index < 0|| (index > (MAX_ITEMS+1)) )
            throw new TFNodeException();
        return nodeChildren[index];
    }
    public void setChild (int index, TFNode child) {
        if ( (index < 0|| (index > (MAX_ITEMS+1)) )
            throw new TFNodeException();
        nodeChildren[index= child;
    }
}
class TFNodeException extends RuntimeException {

    public TFNodeException() {
        super ("Problem with TFNode");
    }
    public TFNodeException(String errorMsg) {
        super (errorMsg);
    }
}
interface Dictionary {

    public int size();
    public boolean isEmpty();

    public Object findElement (Object keythrows ElementNotFoundException;

    public void insertElement (Object key, Object element);

    public Object removeElement (Object keythrows ElementNotFoundException;
}
class ElementNotFoundException  extends RuntimeException
{
    public ElementNotFoundException()
    {

    }
}
class Item {

    private Object itemKey;
    private Object itemElement;

    public Item() {
        this (null, null);
    }

    public Item(Object key, Object element) {
        itemKey = key;
        itemElement = element;
    }

    public Object key() {
        return itemKey;
    }
    public void setKey(Object key) {
        itemKey = key;
    }
    public Object element() {
        return itemElement;
    }
    public void setElement (Object element) {
        itemElement = element;
    }
}interface Comparator {

    public boolean isLessThan (Object obj1, Object obj2);

    public boolean isLessThanOrEqualTo (Object obj1, Object obj2);

    public boolean isGreaterThan (Object obj1, Object obj2);

    public boolean isGreaterThanOrEqualTo (Object obj1, Object obj2);

    public boolean isEqual (Object obj1, Object obj2);

    public boolean isComparable (Object obj);
}class IntegerComparator implements Comparator {

    public IntegerComparator() {
    }

    public boolean isLessThan (Object obj1, Object obj2) {
        Integer myInt1;
        Integer myInt2;
        try {
            myInt1 = (Integerobj1;
            myInt2 = (Integerobj2;
        }
        catch (ClassCastException exc) {
            throw new InvalidIntegerException ("Object not an integer");
        }

        return myInt1.intValue() < myInt2.intValue() );
    }

    public boolean isLessThanOrEqualTo (Object obj1, Object obj2) {
        return ! isLessThan (obj2, obj1) );
    }

    public boolean isGreaterThan (Object obj1, Object obj2) {
        return isLessThan (obj2, obj1) );
    }

    public boolean isGreaterThanOrEqualTo (Object obj1, Object obj2) {
        return ! isLessThan (obj1, obj2) );
    }

    public boolean isEqual (Object obj1, Object obj2) {
        return ( (! isLessThan (obj1, obj2)) && (! isLessThan (obj2, obj1)) );
    }

    public boolean isComparable (Object obj) {
        try {
            Integer myInt = (Integerobj;
            return true;
        }
        catch (ClassCastException exc) {
            return false;
        }
    }
}
class InvalidIntegerException extends RuntimeException {

    public InvalidIntegerException(String errorMsg) {
        super (errorMsg);
    }
}

   
    
    
    
    
  
Related examples in the same category
1.Random-access dictionary
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.