Guest User

Untitled

a guest
Apr 24th, 2018
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.79 KB | None | 0 0
  1.  /*
  2.  * @(#)AVLTree.java
  3.  */
  4.  
  5. package org.eda.actividad03.AVLTree;
  6.  
  7. import java.util.NoSuchElementException;
  8. import java.lang.IllegalStateException;
  9. import java.util.ConcurrentModificationException;
  10.  
  11. import org.eda.estructurasdatos.ALStack;
  12. import org.eda.estructurasdatos.BinarySearchTree;
  13. import org.eda.estructurasdatos.Collection;
  14. import org.eda.estructurasdatos.Iterator;
  15.  
  16. /**
  17.  * This class is a balanced binary tree that implements the Collection interface AVL
  18.  * tree single and double rotation methods.
  19.  * @see     RBTree
  20.  */
  21.  
  22. public class AVLTree<T>
  23.     implements Collection<T>, Iterable<T>, BinarySearchTree<T>
  24. {
  25.     private static int LEFTHEAVY = 1;
  26.     private static int BALANCED = 0;
  27.     private static int RIGHTHEAVY = -1;
  28.    // reference to tree root
  29.    private AVLNode<T> root;
  30.  
  31.    // number of elements in the tree
  32.    private int treeSize;
  33.  
  34.    // increases whenever the tree changes. used by an iterator
  35.    // to verify that it is in a consistent state
  36.    private int modCount;
  37.  
  38.     // delete the tree with a postorder scan of the nodes
  39.     private void deleteTree(AVLNode<T> t)
  40.     {
  41.       // if current root node is not null, delete its left
  42.       // subtree, its right subtree and then set the node to null
  43.       if (t != null)
  44.       {
  45.          deleteTree(t.left);
  46.          deleteTree(t.right);
  47.          t = null;
  48.       }
  49.     }
  50.  
  51.     // iteratively traverse a path from the root to the node
  52.     // whose value is item; return a reference to the node
  53.     // containing item or null if the search fails
  54.     private AVLNode<T> findNode(Object item)
  55.     {
  56.         // t is current node in traversal
  57.         AVLNode<T> t = root;
  58.         int orderValue;
  59.  
  60.         // terminate on on empty subtree
  61.         while(t != null)
  62.         {
  63.             // compare item and the current node value
  64.             orderValue =
  65.                 ((Comparable<T>)item).compareTo(t.nodeValue);
  66.  
  67.             // if a match occurs, return true; otherwise, go left
  68.             // or go right following search tree order
  69.             if (orderValue == 0)
  70.                  return t;
  71.             else if (orderValue < 0)
  72.                  t = t.left;
  73.             else
  74.                  t = t.right;
  75.         }
  76.         return null;
  77.     }
  78.  
  79.     /**
  80.      * Constructs an empty AVL tree. All elements inserted into the
  81.      * tree must implement the <tt>Comparable</tt> interface.
  82.      */
  83.     public AVLTree()
  84.     {
  85.         root = null;
  86.         modCount = 0;
  87.         treeSize = 0;
  88.     }
  89.  
  90.     /**
  91.      * Adds the specified item to this tree if it is not already present.
  92.      *
  93.      * @param item element to be added to this tree.
  94.      * @return <tt>true</tt> if the tree did not already contain the specified
  95.      *         element.
  96.      */
  97.     public boolean add(T item)
  98.     {
  99.         try
  100.         {
  101.             root = addNode(root, item);
  102.         }
  103.  
  104.         catch (IllegalStateException ise)
  105.         { return false; }
  106.  
  107.         // increment the tree size and modCount
  108.         treeSize++;
  109.         modCount++;
  110.  
  111.         // we added a node to the tree
  112.         return true;
  113.     }
  114.  
  115.     private AVLNode<T> addNode(AVLNode<T> t, T item)
  116.     {
  117.         if( t == null )
  118.             t = new AVLNode<T>(item);
  119.         else if (((Comparable<T>)item).compareTo(t.nodeValue) < 0)
  120.         {
  121.             t.left = addNode( t.left, item);
  122.  
  123.             if (height(t.left) - height(t.right) == 2 )
  124.                 if (((Comparable<T>)item).compareTo
  125.                             (t.left.nodeValue) < 0)
  126.                     t = singleRotateRight(t);
  127.                 else
  128.                     t = doubleRotateRight(t);
  129.         }
  130.         else if (((Comparable<T>)item).compareTo
  131.                             (t.nodeValue) > 0 )
  132.         {
  133.             t.right = addNode(t.right, item );
  134.  
  135.             if (height(t.left) - height(t.right) == -2)
  136.                 if (((Comparable<T>)item).compareTo
  137.                             (t.right.nodeValue) > 0)
  138.                     t = singleRotateLeft(t);
  139.                 else
  140.                     t = doubleRotateLeft(t);
  141.         }
  142.         else
  143.             // duplicate; throw IllegalStateException
  144.             throw new IllegalStateException();
  145.  
  146.         t.height = max( height(t.left), height(t.right) ) + 1;
  147.  
  148.         return t;
  149.     }
  150.  
  151.      private static <T> int height(AVLNode<T> t)
  152.      {
  153.          if (t == null)
  154.             return -1;
  155.        else
  156.          return t.height;
  157.      }
  158.  
  159.     private static int max(int a, int b)
  160.     {
  161.         if (a > b)
  162.             return a;
  163.         else
  164.             return b;
  165.     }
  166.  
  167.  
  168.     // perform a single right rotation for parent p
  169.     private static <T> AVLNode<T> singleRotateRight(AVLNode<T> p)
  170.     {
  171.         AVLNode<T> lc = p.left;
  172.  
  173.         p.left = lc.right;
  174.         lc.right = p;
  175.         p.height = max( height( p.left ), height( p.right ) ) + 1;
  176.         lc.height = max( height( lc.left ), lc.height ) + 1;
  177.  
  178.         return lc;
  179.     }
  180.  
  181.     // perform a single left rotation for parent p
  182.     private static <T> AVLNode<T> singleRotateLeft(AVLNode<T> p)
  183.     {
  184.         AVLNode<T> rc = p.right;
  185.  
  186.         p.right = rc.left;
  187.         rc.left = p;
  188.         p.height = max(height(p.left), height(p.right)) + 1;
  189.         rc.height = max(height(rc.right), rc.height) + 1;
  190.  
  191.         return rc;
  192.     }
  193.  
  194.     // perform a double right rotation for parent p
  195.     private static <T> AVLNode<T> doubleRotateRight(AVLNode<T> p)
  196.     {
  197.         p.left = singleRotateLeft(p.left);
  198.         return singleRotateRight(p);
  199.     }
  200.  
  201.     // perform a single left rotation for parent p
  202.     private static <T> AVLNode<T> doubleRotateLeft(AVLNode<T> p)
  203.     {
  204.         p.right = singleRotateRight(p.right);
  205.         return singleRotateLeft(p);
  206.     }
  207.  
  208.     /**
  209.      * Removes all of the elements from this tree. The resulting tree is empty
  210.      * after the method executes.
  211.      */
  212.     public void clear()
  213.     {
  214.         deleteTree(root);
  215.         root = null;
  216.         treeSize = 0;
  217.     }
  218.  
  219.     /**
  220.      * Returns <tt>true</tt> if this tree contains the specified element.
  221.      *
  222.      * @param item the object to be checked for containment in this tree.
  223.      * @return <tt>true</tt> if this tree contains the specified element.
  224.      */
  225.     public boolean contains(Object item)
  226.     {
  227.       AVLNode<T> t = findNode(item);
  228.       return (t == null) ? false : true;
  229.     }
  230.  
  231.       /**
  232.      * Returns <tt>true</tt> if this tree contains no elements.
  233.      *
  234.      * @return <tt>true</tt> if this tree contains no elements.
  235.      */
  236.    public boolean isEmpty()
  237.     {
  238.       return treeSize == 0;
  239.     }
  240.  
  241.     /**
  242.      * Returns an iterator over the elements in this tree.  The elements
  243.      * are returned in ascending order.
  244.      *
  245.      * @return an iterator over the elements in this tree.
  246.      */
  247.     public Iterator<T> iterator()
  248.     {
  249.       return new TreeIterator(root);
  250.     }
  251.  
  252.      /**
  253.      * Returns the number of elements in this tree.
  254.      *
  255.      * @return the number of elements in this tree.
  256.      */
  257.         public int size()
  258.         { return treeSize; }
  259.  
  260.      /**
  261.      * Returns an array containing all of the elements in this tree.
  262.      * The order of elements in the array is the iterator order of elements
  263.      * in the tree
  264.      *
  265.      * @return an array containing all of the elements in this tree
  266.      */
  267.         public Object[] toArray()
  268.         {
  269.             Object[] arr = new Object[treeSize];
  270.             Iterator iter = iterator();
  271.             int i = 0;
  272.  
  273.             while (iter.hasNext())
  274.             {
  275.                 arr[i] = iter.next();
  276.                 i++;
  277.             }
  278.  
  279.             return arr;
  280.         }
  281.  
  282.  
  283.    /**
  284.     * Returns a string representation of this tree. The
  285.     * representation is a comma separated list in iterator order
  286.     * enclosed in square brackets.
  287.     */
  288.     public String toString()
  289.     {
  290.         int i;
  291.  
  292.         // create the return string object
  293.         String returnStr = "[";
  294.         Iterator iter = this.iterator();
  295.  
  296.         // output values separated by commas
  297.         for (i = 0; i < treeSize; i++)
  298.         {
  299.             returnStr += iter.next();
  300.             if (i < treeSize - 1)
  301.                 returnStr += ", ";
  302.         }
  303.         returnStr += "]";
  304.  
  305.         // return the string
  306.         return returnStr;
  307.     }
  308.  
  309.     /**
  310.      * Searches for the specified item in the tree and returns
  311.      * the value of the node that matches item as a key.
  312.      *
  313.      * @param   item   serves as a key to locate an element in the tree..
  314.      * @return  the value of the node that corresponds to item as a key
  315.      *          or <tt>null</tt> if the element is not found.
  316.      */
  317.     public T find(T item)
  318.     {
  319.         AVLNode<T> t = findNode(item);
  320.         T value = null;
  321.  
  322.         if (t != null)
  323.             value = t.nodeValue;
  324.  
  325.         return value;
  326.     }
  327.    
  328.     private class TreeIterator implements Iterator<T>
  329.     {
  330.         private ALStack<AVLNode<T>> stack = null;
  331.         private AVLNode<T> curr = null;
  332.         private AVLNode<T> lastReturned = null;
  333.  
  334.         // set expectedModCount to the number of list changes
  335.         // at the time of iterator creation
  336.         private int expectedModCount = modCount;
  337.  
  338.         // go far left from t, pushing all the nodes with left
  339.         // children on stack
  340.         private AVLNode<T> goFarLeft(AVLNode<T> t)
  341.         {
  342.             if (t == null)
  343.                  return null;
  344.             while (t.left != null)
  345.             {
  346.                  stack.push(t);
  347.                  t = t.left;
  348.             }
  349.             return t;
  350.         }
  351.  
  352.         public TreeIterator(AVLNode<T> root)
  353.         {
  354.             stack = new ALStack<AVLNode<T>>();
  355.             curr = goFarLeft(root);
  356.         }
  357.  
  358.         public boolean hasNext()
  359.         {
  360.             return curr != null;
  361.         }
  362.  
  363.         public T current() {
  364.             return lastReturned.nodeValue;         
  365.         }
  366.  
  367.         public T next()
  368.         {
  369.             // check that the iterator is in a consistent state.
  370.             // throws ConcurrentModificationException if not
  371.             checkIteratorState();
  372.  
  373.             if (curr == null)
  374.                  throw new NoSuchElementException(
  375.                         "No elements remaining");
  376.  
  377.             // capture the value in the node
  378.             T returnValue = (T)curr.nodeValue;
  379.            
  380.             lastReturned = curr;
  381.  
  382.             if (curr.right != null) // have a right subtree
  383.                  // stack nodes on left subtree
  384.                  curr = goFarLeft(curr.right);
  385.             else if (!stack.isEmpty())
  386.                  // no right subtree there are other nodes
  387.                  // to visit. pop the stack
  388.                  curr = (AVLNode<T>)stack.pop();
  389.             else
  390.                  curr = null;   // end of tree; set curr to null
  391.  
  392.             return returnValue;
  393.         }
  394.  
  395.         public void remove()
  396.         {
  397.             // no implementation
  398.         }
  399.  
  400.       // protected so MiniListIteratorImpl class can use it also
  401.       private void checkIteratorState()
  402.       {
  403.          if (expectedModCount != modCount)
  404.             throw new ConcurrentModificationException(
  405.                "Inconsistent iterator");
  406.       }
  407.     }
  408.    
  409.    
  410.     // declares a binary search tree node object
  411.     private static class AVLNode<T>
  412.     {
  413.         // node data
  414.         public T nodeValue;
  415.  
  416.         // child links and link to the node's parent
  417.         public AVLNode<T> left, right;
  418.  
  419.         // public int height;
  420.         public int height;
  421.  
  422.         // constructor that initializes the value, balance factor
  423.         // and parent fields and sets the link fields left and
  424.         // right to null
  425.         public AVLNode(T item)
  426.         {
  427.             nodeValue = item;
  428.             left = null;
  429.             right = null;
  430.             height = 0;
  431.         }
  432.     }
  433.    
  434.     public int height() {
  435.         // TODO Auto-generated method stub
  436.         return height(root);
  437.     }
  438.  
  439.     public int pathHeight(T x) {
  440.         AVLNode<T> t = root;
  441.         int cont = 0, orderValue;
  442.         boolean esta=false;
  443.  
  444.         // terminate on on empty subtree
  445.         while (t != null && esta == false) {
  446.  
  447.             // compare item and the current node value
  448.             orderValue = ((Comparable<T>) x).compareTo(t.nodeValue);
  449.  
  450.             // if a match occurs, return false; otherwise, go left
  451.             // or go right following search tree order
  452.             if (orderValue < 0)
  453.                 t = t.left;
  454.             else if (orderValue > 0)
  455.                 t = t.right;
  456.             else
  457.                 esta = true;
  458.             cont++;
  459.         }
  460.         return (cont-1);
  461.     }
  462.  
  463.     public boolean remove(Object item) {
  464.  
  465.         if (item == null) {
  466.             return false;
  467.         }
  468.  
  469.         try {
  470.             root = remove(root, (T)item);
  471.         } catch (IllegalArgumentException e) {
  472.             return false;
  473.         }
  474.  
  475.         return true;
  476.     }
  477.  
  478.     private AVLNode<T> remove(AVLNode<T> t, T item) {
  479.  
  480.         if (t == null) {
  481.             throw new IllegalArgumentException("Element " + item + " is not present.");
  482.         }
  483.  
  484.         int cmp = ((Comparable<T>)item).compareTo(t.nodeValue);
  485.  
  486.         if (cmp < 0) {
  487.             t.left = remove(t.left, item);
  488.  
  489.             if (height(t.right) - height(t.left) == 2) {
  490.                 if (height(t.right.right) >= height(t.right.left)) {
  491.                     t = singleRotateLeft(t);
  492.                 } else {
  493.                     t = doubleRotateLeft(t);
  494.                 }
  495.             }
  496.         } else if (cmp > 0) {
  497.             t.right = remove(t.right, item);
  498.  
  499.             if (height(t.left) - height(t.right) == 2) {
  500.                 if (height(t.left.left) >= height(t.left.right)) {
  501.                     t = singleRotateRight(t);
  502.                 } else {
  503.                     t = doubleRotateRight(t);
  504.                 }
  505.             }
  506.         } else {
  507.             return removeNode(t);
  508.         }
  509.  
  510.         t.height = Math.max(height(t.left), height(t.right)) + 1;
  511.  
  512.         return t;
  513.     }
  514.  
  515.     private AVLNode<T> removeNode(AVLNode<T> removalNode) {
  516.  
  517.         AVLNode<T> replacementNode;
  518.  
  519.         if (removalNode.left != null && removalNode.right != null) {
  520.             replacementNode = findMin(removalNode.right);
  521.  
  522.             removalNode.right = removeMin(removalNode.right);
  523.  
  524.             replacementNode.left = removalNode.left;
  525.             replacementNode.right = removalNode.right;
  526.  
  527.             if (height(replacementNode.left) - height(replacementNode.right) == 2) {
  528.                 if (height(replacementNode.left.left) >= height(replacementNode.left.right)) {
  529.                     replacementNode = singleRotateRight(replacementNode);
  530.                 } else {
  531.                     replacementNode = doubleRotateRight(replacementNode);
  532.                 }
  533.             }
  534.  
  535.             replacementNode.height = Math.max(height(replacementNode.left), height(replacementNode.right)) + 1;
  536.         } else {
  537.             replacementNode = (removalNode.left != null) ? removalNode.left : removalNode.right;
  538.  
  539.             treeSize--;
  540.         }
  541.  
  542.         removalNode.left = null;
  543.         removalNode.right = null;
  544.  
  545.         return replacementNode;
  546.     }
  547.  
  548.     private AVLNode<T> removeMin(AVLNode<T> t) {
  549.  
  550.         if (t == null) {
  551.             return null;
  552.         }
  553.  
  554.         if (t.left == null) {
  555.             treeSize--;
  556.  
  557.             return t.right;
  558.         }
  559.  
  560.         t.left = removeMin(t.left);
  561.  
  562.         if (height(t.right) - height(t.left) == 2) {
  563.             if (height(t.right.right) >= height(t.right.left)) {
  564.                 t = singleRotateLeft(t);
  565.             } else {
  566.                 t = doubleRotateLeft(t);
  567.             }
  568.         }
  569.  
  570.         t.height = Math.max(height(t.left), height(t.right)) + 1;
  571.  
  572.         return t;
  573.     }
  574.  
  575.     private AVLNode<T> findMin(AVLNode<T> t) {
  576.  
  577.         if (t.left == null) {
  578.             return t;
  579.         }
  580.  
  581.         return findMin(t.left);
  582.     }
  583.  
  584. }
Add Comment
Please, Sign In to add comment