Guest

Untitled

By: a guest on Jan 28th, 2012  |  syntax: None  |  size: 7.48 KB  |  hits: 15  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. package dataStructures.trees;
  2.  
  3. import java.util.*;
  4.  
  5. /**
  6.  * A binary tree of TreeNodes, which contain words in a document.
  7.  *
  8.  * @author Y3761870
  9.  * @version 29/Apr/2009
  10.  */
  11. public class BinaryTree implements Tree
  12. {
  13.         /**
  14.          * The root node of the tree.
  15.          */
  16.     protected TreeNode root = null;
  17.  
  18.     /**
  19.      * Inserts a new word into the tree or updates the record for an existing word with additional locations.
  20.      *  
  21.      * @param data A string containing the data item to be inserted into the Tree
  22.      * @param lineNo The line number the data item appears in the document
  23.      * @param index The offset along the line that the word appears
  24.      */
  25.     public void insert(String data, int lineNo, int index)
  26.     {
  27.                 // if we don't have a root node, create one
  28.         if (root == null)
  29.             root = new TreeNode(data, new WordLocation(lineNo, index));
  30.  
  31.         else
  32.                         // replace the node with a node containing a subtree with the new node in it
  33.             root = insert(root, data, new WordLocation(lineNo, index));
  34.     }
  35.  
  36.         /**
  37.          * Returns a modified subtree with the word inserted or the word's node modified to reflect the new location
  38.          *
  39.          * @param subtree The subtree to be modified
  40.          * @param data The word to be inserted
  41.          * @param location the location of the word
  42.          */
  43.     protected TreeNode insert(TreeNode subtree, String data, WordLocation location)
  44.     {
  45.                 // no need to duplicate the comparison, so store the results
  46.         int comparison = subtree.getData().compareTo(data);
  47.  
  48.                 // element > data
  49.         if (comparison > 0)
  50.         {
  51.                         // if there's no left child
  52.             if (subtree.getLeftChild() == null)
  53.                                 // add a new one
  54.                 subtree.addLeftChild(new TreeNode(data, location));
  55.  
  56.                         // there is a left child
  57.             else
  58.                                 // so delegate the insertion to the left child
  59.                 subtree.addLeftChild(insert(subtree.getLeftChild(), data, location));
  60.         }
  61.  
  62.                 // element < data
  63.         else if (comparison < 0)
  64.         {
  65.             if (subtree.getRightChild() == null)
  66.                 subtree.addRightChild(new TreeNode(data, location));
  67.  
  68.             else
  69.                 subtree.addRightChild(insert(subtree.getRightChild(), data, location));
  70.         }
  71.  
  72.                 // element == data
  73.         else
  74.                         // duplicate, so add the new location
  75.             subtree.addLocation(location);
  76.        
  77.                 // return modified subtree
  78.         return subtree;
  79.     }
  80.  
  81.     /**
  82.      * Remove node with the given data
  83.      *
  84.      * @param data A String containing the data item to be removed from the Tree
  85.      */
  86.     public void remove(String data)
  87.     {
  88.                 // no need to do anything if there's no root node
  89.         if (root != null)
  90.                         // change root to a modified version of the root tree with the relevant data removed
  91.             root = remove(root, data);
  92.     }
  93.    
  94.         /**
  95.          * Gives a modified version of the given node's tree with the relevant data removed (if it exists)
  96.          *
  97.          * @param subtree The subtree to modify
  98.          * @param data The data to remove
  99.          */
  100.     protected TreeNode remove(TreeNode subtree, String data)
  101.     {
  102.         int comparison = subtree.getData().compareTo(data);
  103.  
  104.                 // element > data
  105.         if (comparison > 0)
  106.                         // delegate the removal to the left subtree
  107.             subtree.addLeftChild(remove(subtree.getLeftChild(), data));
  108.  
  109.                 // element < data
  110.         else if (comparison < 0)
  111.             subtree.addRightChild(remove(subtree.getRightChild(), data));
  112.  
  113.                 // element == data
  114.                 // delete this node!
  115.         else
  116.         {
  117.                         // if there's no left child
  118.             if (subtree.getLeftChild() == null)
  119.                                 // then the node is just the right child (this has the effect of making the current node null if the right node is null)
  120.                 subtree = subtree.getRightChild();
  121.            
  122.                         // but if there is a left child
  123.             else
  124.             {
  125.                                 // if there is no right child
  126.                 if (subtree.getRightChild() == null)
  127.                                         // replace the node with its left subtree
  128.                     subtree = subtree.getLeftChild();
  129.  
  130.                 // tree has at least two branches
  131.                 else
  132.                 {
  133.                                         // find the successor (the minimum of the right branch of the node)
  134.                     TreeNode successor = getMinimum(subtree.getRightChild());
  135.  
  136.                                         // remove the original successor, which is now a duplicate
  137.                                         subtree.addRightChild(remove(subtree.getRightChild(), successor.getData()));
  138.                    
  139.                                         // give the successor the children of the current node
  140.                                         successor.addLeftChild(subtree.getLeftChild());
  141.                                         successor.addRightChild(subtree.getRightChild());
  142.                                        
  143.                                         // then make the current node the successor
  144.                                         subtree = successor;
  145.                 }
  146.             }
  147.         }
  148.  
  149.         return subtree;
  150.     }
  151.    
  152.         /**
  153.          * Gets the minimum node (smallest value) from the given subtree.
  154.          *
  155.          * @param node A subtree
  156.          */
  157.     protected TreeNode getMinimum(TreeNode node)
  158.     {
  159.                 // if there are more left children
  160.         if (node.getLeftChild() != null)
  161.                         // this is not left-most (minimum) element, progress further down the tree
  162.             return getMinimum(node.getLeftChild());
  163.  
  164.                 // this is the left-most element, return it.
  165.         return node;
  166.     }
  167.  
  168.     /**
  169.      * Searches for the given word. The ArrayList of WordLocation objects has the location of all occurences of the word in the original document.
  170.          *
  171.      * @param data The word we are looking for
  172.      * @return ArrayList containing all occurences of the word in the document and where each occurance is located
  173.      */
  174.     public ArrayList<WordLocation> find(String data)
  175.     {
  176.                 // if the tree is empty
  177.         if (isEmpty())
  178.                         // return an empty list
  179.             return new ArrayList<WordLocation>();
  180.  
  181.                 // otherwise delegate the finding to the first subtree (from the root)
  182.         return find(root, data);
  183.     }
  184.  
  185.         /**
  186.          * Searches for the given word in the subtree specified.
  187.          *
  188.          * @param node The subtree to search
  189.          * @param data The word we are looking for
  190.          * @return An ArrayList of all occurences of the word
  191.          */
  192.     protected ArrayList<WordLocation> find(TreeNode node, String data)
  193.     {
  194.         int comparison = node.getData().compareTo(data);
  195.  
  196.                 // element > data
  197.         if (comparison > 0)
  198.         {
  199.                         // if we've gotten to the end of the tree
  200.             if (node.getLeftChild() == null)
  201.                                 // just return an empty list
  202.                 return new ArrayList<WordLocation>();
  203.  
  204.             else
  205.                                 // otherwise, delegate to searching the next subtree
  206.                 return find(node.getLeftChild(), data);
  207.         }
  208.  
  209.                 // element < data
  210.         else if (comparison < 0)
  211.         {
  212.             if (node.getRightChild() == null)
  213.                 return new ArrayList<WordLocation>();
  214.  
  215.             else
  216.                 return find(node.getRightChild(), data);
  217.         }
  218.  
  219.                 // element == data
  220.         else
  221.                         // return the list of locations at this node
  222.             return node.getLocations();
  223.     }
  224.  
  225.     /**
  226.      * Checks if a tree is empty
  227.          *
  228.      * @return true if tree is empty
  229.      */
  230.     public boolean isEmpty()
  231.     {
  232.         return (root == null);
  233.     }
  234.  
  235.     /**
  236.      * Remove all nodes from the tree (destructive).
  237.      */
  238.     public void makeEmpty()
  239.     {
  240.         root = null;
  241.     }
  242.  
  243.     /**
  244.      * Provides the root node of the tree (non-destructive)
  245.          *
  246.      * @return TreeNode The node of the Tree
  247.      */
  248.     public TreeNode getRootNode()
  249.     {
  250.         return root;
  251.     }
  252. }