Java TreeMap Special Methods


The TreeMap is a method class collection framework in Java environment. It is storing key to implement a Map Interface or a Map Navigation with a MapAbstract class. After the sorting process the keys of that map will store in the natural order in a consistent manner. The implementation of a TreeMap may not be in an organized manner because the specific map can be addressed by multiple threads. A TreeMap function implemented by using a self-balancing Red-Black binary tree. This method is really efficient to perform addition, remove and retrieve for some elements with O(log n) time complexity.

Now we have some basic idea about the TreeMap. Let's dive into more features of it for better understanding.

What Is TreeMap In Java Environment?

  • TreeMap is a one form of Data Structure which saves the data as a value pair.

  • Here the key is a unique identifier. This method allows to save data of multiple operation (addition, replace and delete).

  • TreeMap is a sorted map just like other, compatible with "=" sign.

  • The TreeMap always maintain an ascending and non-synchronized manner.

  • Fail-fast - It is a class collection view method. The iterator() class return iterators from the collection. They are fail-fast in nature.

  • Comparator interface helps to sort the element by two methods –

    • Key - Associate each value in a map as a unique identifier.

    • Value - Element association by a mapping key.

    • In this method null keys are not allowed and throw Null Pointer Exception.

    • The Red-Black Tree

      • The root node is black.

      • Colouring method keeps insertion and removal ratio in balance.

      • Two red node can't be each other's immediate neighbour.

Algorith

  • Step 1 − Create a new TreeMap.

  • Step 2 − Give some inputs in the TreeMap.

  • Step 3 − Calculate hash key.

  • Step 4 − Terminate the code.

Creating A TreeMap- Syntax

TreeMap<Key, Value> numbers = new TreeMap<>();

The red-black trees show the backend work of the TreeMap() method. The parent element will be always greater than the left one. And the right element is always greater than or equal to the parent element.

Approach to follow

  • Approach 1 − Red-black tree representation in Java

Red-black Tree Representation in Java

Insert the data in a map. Here are some methods to input some data to the map.

  • put() - inserts value

  • putAll() - inserts entries

  • putIfAbsent() - inserts value mapping to the map

Example 1

import java.util.TreeMap;

public class Main {
   public static void main(String[] args) {
        
      TreeMap<String, Integer> evenNumbers = new TreeMap<>();
      evenNumbers.put("Seven", 7);
      evenNumbers.put("Sixteen", 16);
      evenNumbers.putIfAbsent("Ten", 10);
      System.out.println("TreeMap of even numbers here we can get: " + evenNumbers);
      TreeMap<String, Integer> numbers = new TreeMap<>();
      numbers.put("Three", 3);
      numbers.putAll(evenNumbers);
      System.out.println("TreeMap of numbers we get here from list: " + numbers);
   }
}

Output

TreeMap of even numbers here we can get: {Seven=7, Sixteen=16, Ten=10}
TreeMap of numbers we get here from list: {Seven=7, Sixteen=16, Ten=10, Three=3}

Example 2

Java environment provides Red-Black color tree, by which users can maintain the data balance ratio in a map.

class Node {
   int data;
   Node parent;
   Node left;
   Node right;
   int color;
}

public class RedBlackTree {
   private Node root;
   private Node TNULL;
   private void preOrderHelper1(Node node) {
      if (node != TNULL) {
         System.out.print(node.data + " ");
         preOrderHelper1(node.left);
         preOrderHelper1(node.right);
      }
   }
   private void inOrderHelper7(Node node) {
      if (node != TNULL) {
         inOrderHelper7(node.left);
         System.out.print(node.data + " ");
         inOrderHelper7(node.right);
      }
   }
   private void postOrderHelper(Node node) {
      if (node != TNULL) {
         postOrderHelper(node.left);
         postOrderHelper(node.right);
         System.out.print(node.data + " ");
      }
   }
   private Node searchTreeHelper(Node node, int key) {
      if (node == TNULL || key == node.data) {
         return node;
      }

      if (key < node.data) {
         return searchTreeHelper(node.left, key);
      }
      return searchTreeHelper(node.right, key);
   }
   private void fixDelete(Node x) {
      Node s;
      while (x != root && x.color == 0) {
         if (x == x.parent.left) {
            s = x.parent.right;
            if (s.color == 1) {
               s.color = 0;
               x.parent.color = 1;
               leftRotate(x.parent);
               s = x.parent.right;
            }

            if (s.left.color == 0 && s.right.color == 0) {
               s.color = 1;
               x = x.parent;
            } else {
               if (s.right.color == 0) {
                  s.left.color = 0;
                  s.color = 1;
                  rightRotate(s);
                  s = x.parent.right;
               }

               s.color = x.parent.color;
               x.parent.color = 0;
               s.right.color = 0;
               leftRotate(x.parent);
               x = root;
            }
         } else {
            s = x.parent.left;
            if (s.color == 1) {
               s.color = 0;
               x.parent.color = 1;
               rightRotate(x.parent);
               s = x.parent.left;
            }

            if (s.right.color == 0 && s.right.color == 0) {
               s.color = 1;
               x = x.parent;
            } else {
               if (s.left.color == 0) {
                  s.right.color = 0;
                  s.color = 1;
                  leftRotate(s);
                  s = x.parent.left;
               }

               s.color = x.parent.color;
               x.parent.color = 0;
               s.left.color = 0;
               rightRotate(x.parent);
               x = root;
            }
         }
      }
      x.color = 0;
   }

   private void rbTransplant(Node u, Node v) {
      if (u.parent == null) {
         root = v;
      } else if (u == u.parent.left) {
         u.parent.left = v;
      } else {
         u.parent.right = v;
      }
      v.parent = u.parent;
   }

   private void deleteNodeHelper(Node node, int key) {
      Node z = TNULL;
      Node x, y;
      while (node != TNULL) {
         if (node.data == key) {
            z = node;
         }

         if (node.data <= key) {
            node = node.right;
         } else {
            node = node.left;
         }
      }

      if (z == TNULL) {
         System.out.println("Couldn't find key in the tree, please find it again");
         return;
      }

      y = z;
      int yOriginalColor = y.color;
      if (z.left == TNULL) {
         x = z.right;
         rbTransplant(z, z.right);
      } else if (z.right == TNULL) {
         x = z.left;
         rbTransplant(z, z.left);
      } else {
         y = minimum(z.right);
         yOriginalColor = y.color;
         x = y.right;
         if (y.parent == z) {
            x.parent = y;
         } else {
            rbTransplant(y, y.right);
            y.right = z.right;
            y.right.parent = y;
         }

         rbTransplant(z, y);
         y.left = z.left;
         y.left.parent = y;
         y.color = z.color;
      }
      if (yOriginalColor == 0) {
         fixDelete(x);
      }
   }
   private void fixInsert(Node k) {
      Node u;
      while (k.parent.color == 1) {
         if (k.parent == k.parent.parent.right) {
            u = k.parent.parent.left;
            if (u.color == 1) {
               u.color = 0;
               k.parent.color = 0;
               k.parent.parent.color = 1;
               k = k.parent.parent;
            } else {
               if (k == k.parent.left) {
                  k = k.parent;
                  rightRotate(k);
               }
               k.parent.color = 0;
               k.parent.parent.color = 1;
               leftRotate(k.parent.parent);
            }
         } else {
            u = k.parent.parent.right;

            if (u.color == 1) {
               u.color = 0;
               k.parent.color = 0;
               k.parent.parent.color = 1;
               k = k.parent.parent;
            } else {
               if (k == k.parent.right) {
               k = k.parent;
               leftRotate(k);
               }
               k.parent.color = 0;
               k.parent.parent.color = 1;
               rightRotate(k.parent.parent);
            }
         }
         if (k == root) {
            break;
         }
      }
      root.color = 0;
   }

   private void printHelper(Node root, String indent, boolean last) {
      if (root != TNULL) {
         System.out.print(indent);
         if (last) {
            System.out.print("R----");
            indent += " ";
         } else {
            System.out.print("L----");
            indent += "|";
         }

         String sColor = root.color == 1 ? "RED" : "BLACK";
         System.out.println(root.data + "(" + sColor + ")");
         printHelper(root.left, indent, false);
         printHelper(root.right, indent, true);
      }
   }

   public RedBlackTree() {
      TNULL = new Node();
      TNULL.color = 0;
      TNULL.left = null;
      TNULL.right = null;
      root = TNULL;
   }

   public void preorder() {
      preOrderHelper1(this.root);
   }

   public void inorder() {
      inOrderHelper7(this.root);
   }

   public void postorder() {
      postOrderHelper(this.root);
   }

   public Node searchTree(int k) {
      return searchTreeHelper(this.root, k);
   }

   public Node minimum(Node node) {
      while (node.left != TNULL) {
         node = node.left;
      }
      return node;
   }

   public Node maximum(Node node) {
      while (node.right != TNULL) {
         node = node.right;
      }
      return node;
   }

   public Node successor(Node x) {
      if (x.right != TNULL) {
         return minimum(x.right);
      }

      Node y = x.parent;
      while (y != TNULL && x == y.right) {
         x = y;
         y = y.parent;
      }
      return y;
   }

   public Node predecessor(Node x) {
      if (x.left != TNULL) {
         return maximum(x.left);
      }

      Node y = x.parent;
      while (y != TNULL && x == y.left) {
         x = y;
         y = y.parent;
      }

      return y;
   }

   public void leftRotate(Node x) {
      Node y = x.right;
      x.right = y.left;
      if (y.left != TNULL) {
         y.left.parent = x;
      }
      y.parent = x.parent;
      if (x.parent == null) {
         this.root = y;
      } else if (x == x.parent.left) {
         x.parent.left = y;
      } else {
         x.parent.right = y;
      }
      y.left = x;
      x.parent = y;
   }

   public void rightRotate(Node x) {
      Node y = x.left;
      x.left = y.right;
      if (y.right != TNULL) {
         y.right.parent = x;
      }
      y.parent = x.parent;
      if (x.parent == null) {
         this.root = y;
      } else if (x == x.parent.right) {
         x.parent.right = y;
      } else {
         x.parent.left = y;
      }
      y.right = x;
      x.parent = y;
   }

   public void insert(int key) {
      Node node = new Node();
      node.parent = null;
      node.data = key;
      node.left = TNULL;
      node.right = TNULL;
      node.color = 1;

      Node y = null;
      Node x = this.root;

      while (x != TNULL) {
         y = x;
         if (node.data < x.data) {
            x = x.left;
         } else {
            x = x.right;
         }
      }

      node.parent = y;
      if (y == null) {
         root = node;
      } else if (node.data < y.data) {
         y.left = node;
      } else {
         y.right = node;
      }

      if (node.parent == null) {
         node.color = 0;
         return;
      }

      if (node.parent.parent == null) {
         return;
      }

      fixInsert(node);
   }

   public Node getRoot() {
      return this.root;
   }

   public void deleteNode(int data) {
      deleteNodeHelper(this.root, data);
   }

   public void printTree() {
      printHelper(this.root, "", true);
   }

   public static void main(String[] args) {
      RedBlackTree bst = new RedBlackTree();
      bst.insert(07);
      bst.insert(10);
      bst.insert(01);
      bst.insert(16);
      bst.insert(10);
      bst.insert(97);
      bst.printTree();

      System.out.println("\nAfter deleting some elements:");
      bst.deleteNode(97);
      bst.printTree();
   }
}

Output

R----7(BLACK)
 L----1(BLACK)
 R----10(RED)
L----10(BLACK)
R----16(BLACK)
 R----97(RED)

After deleting some elements:
R----7(BLACK)
 L----1(BLACK)
 R----10(RED)
L----10(BLACK)
  R----16(BLACK)

Conclusion

From this article we have learnt about the TreeMap class in detail. We covered here the aspects of the red black tree by TreeMap method. The TreeMap class provides a sorted predictable iteration search performance with the help of Red-Black tree to perform self-balancing in the Java environment.

Updated on: 10-Apr-2023

120 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements