Guest User

Untitled

a guest
Apr 23rd, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.51 KB | None | 0 0
  1. /*
  2.  * @(#)AVLTree.java
  3.  */
  4.  
  5. package org.eda1.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.Iterable;
  15. import org.eda.estructurasdatos.Iterator;
  16.  
  17. /**
  18.  * This class is a balanced binary tree that implements the Collection interface AVL
  19.  * tree single and double rotation methods.
  20.  * @see     RBTree
  21.  */
  22.  
  23. public class AVLTree<T> implements Collection<T>, Iterable<T>, BinarySearchTree<T>{
  24.    // reference to tree root
  25.    private AVLNode<T> root;
  26.  
  27.    // number of elements in the tree
  28.    private int treeSize;
  29.  
  30.    // increases whenever the tree changes. used by an iterator
  31.    // to verify that it is in a consistent state
  32.    private int modCount;
  33.  
  34.     // ...
  35.  
  36.  
  37.     /**
  38.      * Restores balance to the tree given the specified node traversal path and
  39.      * whether insertion or removal was performed.
  40.      *
  41.      * @param nodePath
  42.      *            The Stack which contains the nodes in the order that they were
  43.      *            traversed.
  44.      * @param isInsertion
  45.      *            Indicates whether insertion or removal was performed.
  46.      */
  47.     private void rebalanceAVLTree(ALStack<AVLNode<T>> nodePath, boolean isInsertion) {
  48.  
  49.         AVLNode<T> current;
  50.  
  51.         while (!nodePath.isEmpty()) {
  52.             current = nodePath.pop();
  53.  
  54.             // Check for an imbalance at the current node:
  55.             if (height(current.left) - height(current.right) == 2) {
  56.                 // Compare heights of subtrees of left child node of
  57.                 // imbalanced node (check for single or double rotation case):
  58.                 if (height(current.left.left) >= height(current.left.right)) {
  59.                     // Check if imbalance is internal or at the tree root:
  60.                     if (!nodePath.isEmpty()) {
  61.                         // Compare current element with element of parent
  62.                         // node (check which child reference to update for the
  63.                         // parent node):
  64.                         int cmp = ((Comparable<T>)current.nodeValue).compareTo((nodePath.peek()).nodeValue);
  65.                         if (cmp < 0) {
  66.                             nodePath.peek().left = singleRotateRight(current);
  67.                         } else {
  68.                             nodePath.peek().right = singleRotateRight(current);
  69.                         }
  70.                     } else {
  71.                         root = singleRotateRight(current);
  72.                     }
  73.                 } else {
  74.                     if (!nodePath.isEmpty()) {
  75.                         int cmp = ((Comparable<T>)current.nodeValue).compareTo((nodePath.peek()).nodeValue);
  76.                         if (cmp < 0) {
  77.                             nodePath.peek().left = doubleRotateRight(current);
  78.                         } else {
  79.                             nodePath.peek().right = doubleRotateRight(current);
  80.                         }
  81.                     } else {
  82.                         root = doubleRotateRight(current);
  83.                     }
  84.                 }
  85.  
  86.                 current.height = Math.max(height(current.left),
  87.                         height(current.right)) + 1;
  88.  
  89.                 if (isInsertion) {
  90.                     break;
  91.                 }
  92.             } else if (height(current.right) - height(current.left) == 2) {
  93.                 if (height(current.right.right) >= height(current.right.left)) {
  94.                     if (!nodePath.isEmpty()) {
  95.                         int cmp = ((Comparable<T>)current.nodeValue).compareTo((nodePath.peek()).nodeValue);
  96.                         if (cmp < 0) {
  97.                             nodePath.peek().left = singleRotateLeft(current);
  98.                         } else {
  99.                             nodePath.peek().right = singleRotateLeft(current);
  100.                         }
  101.                     } else {
  102.                         root = singleRotateLeft(current);
  103.                     }
  104.                 } else {
  105.                     if (!nodePath.isEmpty()) {
  106.                         int cmp = ((Comparable<T>)current.nodeValue).compareTo((nodePath.peek()).nodeValue);
  107.                         if (cmp < 0) {
  108.                             nodePath.peek().left = doubleRotateLeft(current);
  109.                         } else {
  110.                             nodePath.peek().right = doubleRotateLeft(current);
  111.                         }
  112.                     } else {
  113.                         root = doubleRotateLeft(current);
  114.                     }
  115.                 }
  116.  
  117.                 current.height = Math.max(height(current.left),
  118.                         height(current.right)) + 1;
  119.  
  120.                 if (isInsertion) {
  121.                     break;
  122.                 }
  123.             } else {
  124.                 current.height = Math.max(height(current.left),
  125.                         height(current.right)) + 1;
  126.             }
  127.         }
  128.     }
  129.  
  130.     // ...
  131.  
  132.     /**
  133.      * Adds the specified item to this tree if it is not already present.
  134.      *
  135.      * @param item element to be added to this tree.
  136.      * @return <tt>true</tt> if the tree did not already contain the specified
  137.      *         element.
  138.      */
  139.     public boolean add(T item)
  140.     {
  141.         try
  142.         {
  143.             root = addNode(root, item);
  144.         }
  145.  
  146.         catch (IllegalStateException ise)
  147.         { return false; }
  148.  
  149.         // increment the tree size and modCount
  150.         treeSize++;
  151.         modCount++;
  152.  
  153.         // test
  154.         //testBalanceFactor(root);
  155.         //testHeight(root);
  156.  
  157.         // we added a node to the tree
  158.         return true;
  159.     }
  160.  
  161.     private AVLNode<T> addNode(AVLNode<T> t, T item)
  162.     {
  163.         if( t == null )
  164.             t = new AVLNode<T>(item);
  165.         else if (((Comparable<T>)item).compareTo(t.nodeValue) < 0)
  166.         {
  167.             t.left = addNode( t.left, item);
  168.  
  169.             if (height(t.left) - height(t.right) == 2 )
  170.                 if (((Comparable<T>)item).compareTo
  171.                             (t.left.nodeValue) < 0)
  172.                     t = singleRotateRight(t);
  173.                 else
  174.                     t = doubleRotateRight(t);
  175.         }
  176.         else if (((Comparable<T>)item).compareTo
  177.                             (t.nodeValue) > 0 )
  178.         {
  179.             t.right = addNode(t.right, item );
  180.  
  181.             if (height(t.left) - height(t.right) == -2)
  182.                 if (((Comparable<T>)item).compareTo
  183.                             (t.right.nodeValue) > 0)
  184.                     t = singleRotateLeft(t);
  185.                 else
  186.                     t = doubleRotateLeft(t);
  187.         }
  188.         else
  189.             // duplicate; throw IllegalStateException
  190.             throw new IllegalStateException();
  191.  
  192.         t.height = max( height(t.left), height(t.right) ) + 1;
  193.  
  194.         return t;
  195.     }
  196.  
  197.     /**
  198.      * Adds (iterative) the specified data item into this AVLTree, if the item is
  199.      * not already present.
  200.      *
  201.      * @param item
  202.      *            The item to be inserted.
  203.      * @return True if insertion is performed.
  204.      */
  205.     public boolean addIterative(T item) {
  206.  
  207.         if (item == null) {
  208.             return false;
  209.         }
  210.  
  211.         ALStack<AVLNode<T>> nodePath = new ALStack<AVLNode<T>>();
  212.  
  213.         AVLNode<T> current = root;
  214.  
  215.         while (current != null) {
  216.             nodePath.push(current);
  217.  
  218.             int cmp = ((Comparable<T>)item).compareTo(current.nodeValue);
  219.  
  220.             if (cmp < 0) {
  221.                 if (current.left == null) {
  222.                     current.left = new AVLNode<T>(item);
  223.  
  224.                     treeSize++;
  225.  
  226.                     rebalanceAVLTree(nodePath, true);
  227.  
  228.                     return true;
  229.                 }
  230.  
  231.                 current = current.left;
  232.             } else if (cmp > 0) {
  233.                 if (current.right == null) {
  234.                     current.right = new AVLNode<T>(item);
  235.  
  236.                     treeSize++;
  237.  
  238.                     rebalanceAVLTree(nodePath, true);
  239.  
  240.                     return true;
  241.                 }
  242.  
  243.                 current = current.right;
  244.             } else {
  245.                 return false; // Element is already stored in tree
  246.             }
  247.         }
  248.  
  249.         // Tree is empty:
  250.         root = new AVLNode<T>(item);
  251.  
  252.         treeSize++;
  253.  
  254.         return true;
  255.     }
  256.  
  257.     public boolean remove(Object item) {
  258.  
  259.         if (item == null) {
  260.             return false;
  261.         }
  262.  
  263.         try {
  264.             root = remove(root, (T)item);
  265.         } catch (IllegalArgumentException e) {
  266.             return false;
  267.         }
  268.  
  269.         return true;
  270.     }
  271.  
  272.     private AVLNode<T> remove(AVLNode<T> t, T item) {
  273.  
  274.         if (t == null) {
  275.             throw new IllegalArgumentException("Element " + item + " is not present.");
  276.         }
  277.  
  278.         int cmp = ((Comparable<T>)item).compareTo(t.nodeValue);
  279.  
  280.         if (cmp < 0) {
  281.             t.left = remove(t.left, item);
  282.  
  283.             if (height(t.right) - height(t.left) == 2) {
  284.                 if (height(t.right.right) >= height(t.right.left)) {
  285.                     t = singleRotateLeft(t);
  286.                 } else {
  287.                     t = doubleRotateLeft(t);
  288.                 }
  289.             }
  290.         } else if (cmp > 0) {
  291.             t.right = remove(t.right, item);
  292.  
  293.             if (height(t.left) - height(t.right) == 2) {
  294.                 if (height(t.left.left) >= height(t.left.right)) {
  295.                     t = singleRotateRight(t);
  296.                 } else {
  297.                     t = doubleRotateRight(t);
  298.                 }
  299.             }
  300.         } else {
  301.             return removeNode(t);
  302.         }
  303.  
  304.         t.height = Math.max(height(t.left), height(t.right)) + 1;
  305.  
  306.         return t;
  307.     }
  308.  
  309.     private AVLNode<T> removeNode(AVLNode<T> removalNode) {
  310.  
  311.         AVLNode<T> replacementNode;
  312.  
  313.         if (removalNode.left != null && removalNode.right != null) {
  314.             replacementNode = findMin(removalNode.right);
  315.  
  316.             removalNode.right = removeMin(removalNode.right);
  317.  
  318.             replacementNode.left = removalNode.left;
  319.             replacementNode.right = removalNode.right;
  320.  
  321.             if (height(replacementNode.left) - height(replacementNode.right) == 2) {
  322.                 if (height(replacementNode.left.left) >= height(replacementNode.left.right)) {
  323.                     replacementNode = singleRotateRight(replacementNode);
  324.                 } else {
  325.                     replacementNode = doubleRotateRight(replacementNode);
  326.                 }
  327.             }
  328.  
  329.             replacementNode.height = Math.max(height(replacementNode.left), height(replacementNode.right)) + 1;
  330.         } else {
  331.             replacementNode = (removalNode.left != null) ? removalNode.left : removalNode.right;
  332.  
  333.             treeSize--;
  334.         }
  335.  
  336.         removalNode.left = null;
  337.         removalNode.right = null;
  338.  
  339.         return replacementNode;
  340.     }
  341.  
  342.     private AVLNode<T> removeMin(AVLNode<T> t) {
  343.  
  344.         if (t == null) {
  345.             return null;
  346.         }
  347.  
  348.         if (t.left == null) {
  349.             treeSize--;
  350.  
  351.             return t.right;
  352.         }
  353.  
  354.         t.left = removeMin(t.left);
  355.  
  356.         if (height(t.right) - height(t.left) == 2) {
  357.             if (height(t.right.right) >= height(t.right.left)) {
  358.                 t = singleRotateLeft(t);
  359.             } else {
  360.                 t = doubleRotateLeft(t);
  361.             }
  362.         }
  363.  
  364.         t.height = Math.max(height(t.left), height(t.right)) + 1;
  365.  
  366.         return t;
  367.     }
  368.  
  369.     private AVLNode<T> findMin(AVLNode<T> t) {
  370.  
  371.         if (t.left == null) {
  372.             return t;
  373.         }
  374.  
  375.         return findMin(t.left);
  376.     }
  377.  
  378.     /**
  379.      * Removes (iterative) the specified data item from this AVLTree, if the item is
  380.      * present.
  381.      *
  382.      * @param item
  383.      *            The item to be removed.
  384.      * @return True if removal is performed.
  385.      */
  386.     public boolean removeIterative(T item) {
  387.  
  388.         if (item == null) {
  389.             return false;
  390.         }
  391.  
  392.         ALStack<AVLNode<T>> nodePath = new ALStack<AVLNode<T>>();
  393.  
  394.         AVLNode<T> current = root;
  395.  
  396.         while (current != null) {
  397.             nodePath.push(current);
  398.  
  399.             int cmp = ((Comparable<T>)item).compareTo(current.nodeValue);
  400.  
  401.             if (cmp < 0) {
  402.                 if ((current.left != null) && (item.equals(current.left.nodeValue))) {
  403.                     current.left = removeNodeIterative(current.left);
  404.  
  405.                     treeSize--;
  406.  
  407.                     rebalanceAVLTree(nodePath, false);
  408.  
  409.                     return true;
  410.                 }
  411.  
  412.                 current = current.left;
  413.             } else if (cmp > 0) {
  414.                 if ((current.right != null) && (item.equals(current.right.nodeValue))) {
  415.                     current.right = removeNodeIterative(current.right);
  416.  
  417.                     treeSize--;
  418.  
  419.                     rebalanceAVLTree(nodePath, false);
  420.  
  421.                     return true;
  422.                 }
  423.  
  424.                 current = current.right;
  425.             } else {
  426.                 root = removeNodeIterative(current); // Root is to be removed
  427.  
  428.                 treeSize--;
  429.  
  430.                 rebalanceAVLTree(nodePath, false);
  431.  
  432.                 return true;
  433.             }
  434.         }
  435.  
  436.         return false;
  437.     }
  438.  
  439.     /**
  440.      * Removes (iterative) the specified node from the AVLTree, returning an appropriate
  441.      * replacement node.
  442.      *
  443.      * @param removalNode
  444.      *            The node to be removed from the tree.
  445.      * @return The node to replace the removed node.
  446.      */
  447.     private AVLNode<T> removeNodeIterative(AVLNode<T> removalNode) {
  448.  
  449.         AVLNode<T> replacementNode;
  450.  
  451.         if ((removalNode.left != null) && (removalNode.right != null)) {
  452.             replacementNode = fetchSuccessor(removalNode);
  453.  
  454.             replacementNode.left = removalNode.left;
  455.             replacementNode.right = removalNode.right;
  456.  
  457.             if (height(replacementNode.left)
  458.                     - height(replacementNode.right) == 2) {
  459.                 if (height(replacementNode.left.left) >= height(replacementNode.left.right)) {
  460.                     replacementNode = singleRotateRight(replacementNode);
  461.                 } else {
  462.                     replacementNode = doubleRotateRight(replacementNode);
  463.                 }
  464.             }
  465.  
  466.             replacementNode.height = Math.max(height(replacementNode.left),
  467.                     height(replacementNode.right)) + 1;
  468.         } else {
  469.             replacementNode = (removalNode.left != null) ? removalNode.left
  470.                     : removalNode.right;
  471.         }
  472.  
  473.         removalNode.left = null;
  474.         removalNode.right = null;
  475.  
  476.         return replacementNode;
  477.     }
  478.  
  479.     /**
  480.      * Removes and returns the node that is the logical in-order successor of
  481.      * the specified subtree root node.
  482.      *
  483.      * @param sRoot
  484.      *            The root of the subtree of which to fetch the logical
  485.      *            successor node.
  486.      * @return The successor node of the specified subtree root node.
  487.      */
  488.     private AVLNode<T> fetchSuccessor(AVLNode<T> sRoot) {
  489.  
  490.         if ((sRoot == null) || (sRoot.right == null)) {
  491.             return null;
  492.         }
  493.  
  494.         AVLNode<T> successorNode = sRoot.right;
  495.  
  496.         if (sRoot.right.left == null) {
  497.             sRoot.right = successorNode.right;
  498.  
  499.             return successorNode;
  500.         } else {
  501.             ALStack<AVLNode<T>> nodePath = new ALStack<AVLNode<T>>();
  502.  
  503.             nodePath.push(sRoot);
  504.  
  505.             AVLNode<T> current = sRoot.right;
  506.  
  507.             while (current.left.left != null) {
  508.                 nodePath.push(current);
  509.  
  510.                 current = current.left;
  511.             }
  512.  
  513.             nodePath.push(current);
  514.  
  515.             successorNode = current.left;
  516.  
  517.             current.left = current.left.right;
  518.  
  519.             rebalanceTreeAfterFetchSuccessor(nodePath);
  520.  
  521.             return successorNode;
  522.         }
  523.     }
  524.  
  525.     /**
  526.      * Restores balance to the tree after a node successor has been fetched
  527.      * given the specified node traversal path.
  528.      *
  529.      * @param nodePath
  530.      *            The Stack which contains the nodes in the order that they were
  531.      *            traversed.
  532.      */
  533.     private void rebalanceTreeAfterFetchSuccessor(ALStack<AVLNode<T>> nodePath) {
  534.  
  535.         AVLNode<T> current;
  536.  
  537.         while (nodePath.size() > 2) {
  538.             current = nodePath.pop();
  539.  
  540.             if (height(current.right) - height(current.left) == 2) {
  541.                 if (height(current.right.right) >= height(current.right.left)) {
  542.                     nodePath.peek().left = singleRotateLeft(current);
  543.                 } else {
  544.                     nodePath.peek().left = doubleRotateLeft(current);
  545.                 }
  546.             }
  547.  
  548.             current.height = Math.max(height(current.left),
  549.                     height(current.right)) + 1;
  550.         }
  551.  
  552.         // Current node is root of right subtree of removal node:
  553.         current = nodePath.pop();
  554.  
  555.         if (height(current.right) - height(current.left) == 2) {
  556.             if (height(current.right.right) >= height(current.right.left)) {
  557.                 nodePath.peek().right = singleRotateLeft(current);
  558.             } else {
  559.                 nodePath.peek().right = doubleRotateLeft(current);
  560.             }
  561.         }
  562.  
  563.         current.height = Math.max(height(current.left),
  564.                 height(current.right)) + 1;
  565.     }
  566.  
  567.     // ...
  568.  
  569.     // declares a binary search tree node object
  570.     private static class AVLNode<T>
  571.     {
  572.         // node data
  573.         public T nodeValue;
  574.  
  575.         // child links and link to the node's parent
  576.         public AVLNode<T> left, right;
  577.  
  578.         // public int height;
  579.         public int height;
  580.  
  581.         // constructor that initializes the value, balance factor
  582.         // and parent fields and sets the link fields left and
  583.         // right to null
  584.         public AVLNode(T item)
  585.         {
  586.             nodeValue = item;
  587.             left = null;
  588.             right = null;
  589.             height = 0;
  590.         }
  591.     }
  592. }
Add Comment
Please, Sign In to add comment