Advertisement
Manioc

RB Tree

Jul 16th, 2018
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.92 KB | None | 0 0
  1. package adt.rbtree;
  2.  
  3. import adt.bst.BSTImpl;
  4. import adt.bst.BSTNode;
  5. import adt.rbtree.RBNode.Colour;
  6.  
  7. public class RBTreeImpl<T extends Comparable<T>> extends BSTImpl<T>
  8.         implements RBTree<T> {
  9.  
  10.     public RBTreeImpl() {
  11.         this.root = new RBNode<T>();
  12.     }
  13.  
  14.     protected int blackHeight() {
  15.         // TODO Implement your code here
  16.         throw new UnsupportedOperationException("Not implemented yet!");
  17.     }
  18.  
  19.     protected boolean verifyProperties() {
  20.         boolean resp = verifyNodesColour() && verifyNILNodeColour()
  21.                 && verifyRootColour() && verifyChildrenOfRedNodes()
  22.                 && verifyBlackHeight();
  23.  
  24.         return resp;
  25.     }
  26.  
  27.     /**
  28.      * The colour of each node of a RB tree is black or red. This is guaranteed
  29.      * by the type Colour.
  30.      */
  31.     private boolean verifyNodesColour() {
  32.         return true; // already implemented
  33.     }
  34.  
  35.     /**
  36.      * The colour of the root must be black.
  37.      */
  38.     private boolean verifyRootColour() {
  39.         return ((RBNode<T>) root).getColour() == Colour.BLACK; // already
  40.                                                                 // implemented
  41.     }
  42.  
  43.     /**
  44.      * This is guaranteed by the constructor.
  45.      */
  46.     private boolean verifyNILNodeColour() {
  47.         return true; // already implemented
  48.     }
  49.  
  50.     /**
  51.      * Verifies the property for all RED nodes: the children of a red node must
  52.      * be BLACK.
  53.      */
  54.     private boolean verifyChildrenOfRedNodes() {
  55.         return this.verifyChildrenOfRedNodes((RBNode<T>) this.root);
  56.     }
  57.    
  58.     private boolean verifyChildrenOfRedNodes(RBNode<T> node) {
  59.         if(node.isLeaf()) return true;
  60.        
  61.         boolean left;
  62.         boolean right;
  63.         if(node.getColour().equals(Colour.RED)) {
  64.             if(node.getLeft().equals(Colour.RED)) return false;
  65.             if(node.getRight().equals(Colour.RED)) return false;
  66.         }
  67.        
  68.         left = this.verifyChildrenOfRedNodes((RBNode<T>)node.getLeft());
  69.         right = this.verifyChildrenOfRedNodes((RBNode<T>) node.getRight());
  70.        
  71.         return left && right;
  72.     }
  73.  
  74.     /**
  75.      * Verifies the black-height property from the root. The method blackHeight
  76.      * returns an exception if the black heights are different.
  77.      */
  78.     private boolean verifyBlackHeight() {
  79.         if(!this.root.isEmpty()) {
  80.             return blackHeight((RBNode<T>) this.root.getLeft()) == blackHeight((RBNode<T>) this.root.getRight());
  81.         }
  82.         return true;
  83.     }
  84.    
  85.     private int blackHeight(RBNode<T> node) {
  86.         if(node.isEmpty()) return 1;
  87.        
  88.         if(node.getColour().equals(Colour.BLACK)) return 1 + blackHeight( (RBNode<T>)node.getLeft()) + blackHeight((RBNode<T>)node.getRight());
  89.         else return blackHeight( (RBNode<T>)node.getLeft()) + blackHeight((RBNode<T>)node.getRight());
  90.     }
  91.    
  92.     @Override
  93.     public void insert(T value) {
  94.         super.insert(value);
  95.         RBNode<T> node = (RBNode<T>)super.search(value);
  96.         node.setColour(Colour.RED);
  97.         this.fixUpCase1(node);
  98.     }
  99.  
  100.     @Override
  101.     public RBNode<T>[] rbPreOrder() {
  102.         RBNode<T>[] arr = new RBNode[this.size()];
  103.         if(!this.isEmpty()) rbpreOrder((RBNode<T>) this.root, arr, 0);
  104.         return arr;
  105.     }
  106.  
  107.     private int rbpreOrder(RBNode<T> no, RBNode<T>[] arr, int idx) {
  108.         if(!no.isEmpty()) {
  109.             arr[idx++] = no;
  110.             idx = rbpreOrder((RBNode<T>) no.getLeft(), arr, idx);
  111.             idx = rbpreOrder((RBNode<T>) no.getRight(), arr, idx);
  112.         }
  113.         return idx;
  114.     }
  115.    
  116.     public RBNode<T> leftRotation(RBNode<T> node) {
  117.         RBNode y = (RBNode)node.getRight();
  118.        
  119.         if(node.getParent() != null) {
  120.             if(node.getParent().getRight().equals(node)) node.getParent().setRight(y);
  121.             else node.getParent().setLeft(y);
  122.         }
  123.         y.setParent(node.getParent());
  124.         node.setParent(y);
  125.         if(y.getLeft() != null) {
  126.             node.setRight(y.getLeft());
  127.             y.getLeft().setParent(node);
  128.         }
  129.         y.setLeft(node);
  130.        
  131.         return y;
  132.        
  133.     }
  134.  
  135.     public RBNode<T> rightRotation(RBNode<T> node) {
  136.         RBNode y = (RBNode)node.getLeft();
  137.        
  138.         if(node.getParent() != null) {
  139.             if(node.getParent().getLeft().equals(node)) node.getParent().setLeft(y);
  140.             else node.getParent().setRight(y);
  141.         }
  142.        
  143.         y.setParent(node.getParent());
  144.         node.setParent(y);
  145.         if(y.getRight() != null) {
  146.             node.setLeft(y.getRight());
  147.             y.getRight().setParent(node);
  148.         }
  149.         y.setRight(node);
  150.        
  151.         return y;
  152.     }
  153.    
  154.      protected void toLeft(RBNode<T> node) {
  155.             RBNode<T> center = leftRotation(node);
  156.             if(node.equals(this.root)) this.root = center;
  157.         }
  158.        
  159.         protected void toRight(RBNode<T> node) {
  160.             RBNode<T> center = rightRotation(node);
  161.             if(node.equals(this.root)) this.root = center;
  162.         }
  163.     // FIXUP methods
  164.     protected void fixUpCase1(RBNode<T> node) {
  165.         if(node.equals(root)) ((RBNode<T>) this.root).setColour(Colour.BLACK);
  166.         else fixUpCase2(node);
  167.     }
  168.  
  169.     protected void fixUpCase2(RBNode<T> node) {
  170.         if(!((RBNode<T>)node.getParent()).getColour().equals(Colour.BLACK)) {
  171.             this.fixUpCase3(node);
  172.         }
  173.     }
  174.  
  175.     protected void fixUpCase3(RBNode<T> node) {
  176.         RBNode<T> tio = (RBNode<T>) node.getParent().getParent();
  177.         if(tio.getLeft().equals(node.getParent())) tio = (RBNode<T>) tio.getRight();
  178.         else tio = (RBNode<T>) tio.getLeft();
  179.        
  180.         if(tio.getColour().equals(Colour.RED)) {
  181.             ((RBNode<T>)node.getParent()).setColour(Colour.BLACK);
  182.             tio.setColour(Colour.BLACK);
  183.             ((RBNode<T>)tio.getParent()).setColour(Colour.RED);
  184.             this.fixUpCase1(node);
  185.         }else this.fixUpCase4(node);
  186.     }
  187.  
  188.     protected void fixUpCase4(RBNode<T> node) {
  189.         RBNode<T> next = node;
  190.         RBNode<T> pai = (RBNode<T>)node.getParent();
  191.         if(pai.getParent().getLeft().equals(pai)) {
  192.             if(pai.getRight().equals(node)){
  193.                 this.toLeft(pai);
  194.                 next = (RBNode<T>) node.getLeft();
  195.             }
  196.         }else {
  197.             if(pai.getLeft().equals(node)) {
  198.                 this.toRight(pai);
  199.                 next = (RBNode<T>) node.getRight();
  200.             }
  201.         }
  202.        
  203.         this.fixUpCase5(next);
  204.     }
  205.  
  206.     protected void fixUpCase5(RBNode<T> node) {
  207.         RBNode<T> pai = (RBNode<T>) node.getParent();
  208.         pai.setColour(Colour.BLACK);
  209.        
  210.         RBNode<T> avo = (RBNode<T>) node.getParent().getParent();
  211.        
  212.         if(pai.getRight().equals(node)){
  213.             this.toLeft(avo);
  214.         }else this.toRight(avo);
  215.     }
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement