Author: saqibkhan

  • Graph

    Overview

    Graph is a datastructure to model the mathematical graphs. It consists of a set of connected pairs called edges of vertices. We can represent a graph using an array of vertices and a two dimentional array of edges.

    Important terms

    • Vertex − Each node of the graph is represented as a vertex. In example given below, labeled circle represents vertices. So A to G are vertices. We can represent them using an array as shown in image below. Here A can be identified by index 0. B can be identified using index 1 and so on.
    • Edge − Edge represents a path between two vertices or a line between two vertices. In example given below, lines from A to B, B to C and so on represents edges. We can use a two dimentional array to represent array as shown in image below. Here AB can be represented as 1 at row 0, column 1, BC as 1 at row 1, column 2 and so on, keeping other combinations as 0.
    • Adjacency − Two node or vertices are adjacent if they are connected to each other through an edge. In example given below, B is adjacent to A, C is adjacent to B and so on.
    • Path − Path represents a sequence of edges betweeen two vertices. In example given below, ABCD represents a path from A to D.

    Basic Operations

    Following are basic primary operations of a Graph which are following.

    • Add Vertex − add a vertex to a graph.
    • Add Edge − add an edge between two vertices of a graph.
    • Display Vertex − display a vertex of a graph.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Add Vertex Operation

    //add vertex to the array of vertex
    public void addVertex(char label){
       lstVertices[vertexCount++] = new Vertex(label);
    }

    Add Edge Operation

    //add edge to edge array
    public void addEdge(int start,int end){
       adjMatrix[start][end] = 1;
       adjMatrix[end][start] = 1;
    }

    Display Edge Operation

    //display the vertex
    public void displayVertex(int vertexIndex){
       System.out.print(lstVertices[vertexIndex].label+" ");
    }   

    Traversal Algorithms

    Following are important traversal algorithms on a Graph.

    • Depth First Search − traverses a graph in depthwards motion.
    • Breadth First Search − traverses a graph in breadthwards motion.

    Depth First Search Algorithm

    Depth First Search algorithm(DFS) traverses a graph in a depthward motion and uses a stack to remember to get the next vertex to start a search when a dead end occurs in any iteration.

    As in example given above, DFS algorithm traverses from A to B to C to D first then to E, then to F and lastly to G. It employs following rules.

    • Rule 1 − Visit adjacent unvisited vertex. Mark it visited. Display it. Push it in a stack.
    • Rule 2 − If no adjacent vertex found, pop up a vertex from stack. (It will pop up all the vertices from the stack which do not have adjacent vertices.)
    • Rule 3 − Repeat Rule 1 and Rule 2 until stack is empty.
    public void depthFirstSearch(){
       //mark first node as visited
       lstVertices[0].visited = true;
       //display the vertex
       displayVertex(0);   
       //push vertex index in stack
       stack.push(0);
    
       while(!stack.isEmpty()){
    
      //get the unvisited vertex of vertex which is at top of the stack
      int unvisitedVertex = getAdjUnvisitedVertex(stack.peek());
      //no adjacent vertex found
      if(unvisitedVertex == -1){
         stack.pop();
      }else{
         lstVertices[unvisitedVertex].visited = true;
         displayVertex(unvisitedVertex);
         stack.push(unvisitedVertex);
      }
    } //stack is empty, search is complete, reset the visited flag for(int i=0;i<vertexCount;i++){
      lstVertices&#91;i].visited = false;
    } }

    Breadth First Search Algorithm

    Breadth First Search algorithm(BFS) traverses a graph in a breadthwards motion and uses a queue to remember to get the next vertex to start a search when a dead end occurs in any iteration.

    As in example given above, BFS algorithm traverses from A to B to E to F first then to C and G lastly to D. It employs following rules.

    • Rule 1 − Visit adjacent unvisited vertex. Mark it visited. Display it. Insert it in a queue.
    • Rule 2 − If no adjacent vertex found, remove the first vertex from queue.
    • Rule 3 − Repeat Rule 1 and Rule 2 until queue is empty.
    public void breadthFirstSearch(){
       //mark first node as visited
       lstVertices[0].visited = true;
       //display the vertex
       displayVertex(0);   
       //insert vertex index in queue
       queue.insert(0);
    
       int unvisitedVertex;
       while(!queue.isEmpty()){
    
      //get the unvisited vertex of vertex which is at front of the queue
      int tempVertex = queue.remove();            
      //no adjacent vertex found
      while((unvisitedVertex=getAdjUnvisitedVertex(tempVertex)) != -1){    
         lstVertices&#91;unvisitedVertex].visited = true;
         displayVertex(unvisitedVertex);
         queue.insert(unvisitedVertex);               
      }
    } //queue is empty, search is complete, reset the visited flag for(int i=0;i<vertexCount;i++){
      lstVertices&#91;i].visited = false;
    } }

    Graph Implementation

    Stack.java

    package com.tutorialspoint.datastructure;
    
    public class Stack {
       private int size;           // size of the stack
       private int[] intArray;     // stack storage
       private int top;            // top of the stack
    
       // Constructor 
       public Stack(int size){
    
      this.size = size;           
      intArray = new int&#91;size];   //initialize array
      top = -1;                   //stack is initially empty
    } // Operation : Push // push item on the top of the stack public void push(int data) {
      if(!isFull()){
         // increment top by 1 and insert data 
         intArray&#91;++top] = data;
      }else{
         System.out.println("Cannot add data. Stack is full.");
      }      
    } // Operation : Pop // pop item from the top of the stack public int pop() {
      //retrieve data and decrement the top by 1
      return intArray&#91;top--];        
    } // Operation : Peek // view the data at top of the stack public int peek() {
      //retrieve data from the top
      return intArray&#91;top];
    } // Operation : isFull // return true if stack is full public boolean isFull(){
      return (top == size-1);
    } // Operation : isEmpty // return true if stack is empty public boolean isEmpty(){
      return (top == -1);
    } }

    Queue.java

    package com.tutorialspoint.datastructure;
    
    public class Queue {
    
    private final int MAX; private int[] intArray; private int front; private int rear; private int itemCount; public Queue(int size){
      MAX = size;
      intArray = new int&#91;MAX];
      front = 0;
      rear = -1;
      itemCount = 0;
    } public void insert(int data){
      if(!isFull()){
         if(rear == MAX-1){
            rear = -1;            
         }       
         intArray&#91;++rear] = data;
         itemCount++;
      }
    } public int remove(){
      int data = intArray&#91;front++];
      if(front == MAX){
         front = 0;
      }
      itemCount--;
      return data;  
    } public int peek(){
      return intArray&#91;front];
    } public boolean isEmpty(){
      return itemCount == 0;
    } public boolean isFull(){
      return itemCount == MAX;
    } public int size(){
      return itemCount;
    } }

    Vertex.java

    package com.tutorialspoint.datastructure;
    
    public class Vertex {
       public char label;
       public boolean visited;
    
       public Vertex(char label){
    
      this.label = label;
      visited = false;
    } }

    Graph.java

    package com.tutorialspoint.datastructure;
    
    public class Graph {
       private final int MAX = 20;
       //array of vertices
       private Vertex lstVertices[];
       //adjacency matrix
       private int adjMatrix[][];
       //vertex count
       private int vertexCount;
    
       private Stack stack;
       private Queue queue;
    
       public Graph(){
    
      lstVertices = new Vertex&#91;MAX];
      adjMatrix = new int&#91;MAX]&#91;MAX];
      vertexCount = 0;
      stack = new Stack(MAX);
      queue = new Queue(MAX);
      for(int j=0; j&lt;MAX; j++) // set adjacency
         for(int k=0; k&lt;MAX; k++) // matrix to 0
            adjMatrix&#91;j]&#91;k] = 0;
    } //add vertex to the vertex list public void addVertex(char label){
      lstVertices&#91;vertexCount++] = new Vertex(label);
    } //add edge to edge array public void addEdge(int start,int end){
      adjMatrix&#91;start]&#91;end] = 1;
      adjMatrix&#91;end]&#91;start] = 1;
    } //display the vertex public void displayVertex(int vertexIndex){
      System.out.print(lstVertices&#91;vertexIndex].label+" ");
    } //get the adjacent unvisited vertex public int getAdjUnvisitedVertex(int vertexIndex){
      for(int i=0; i&lt;vertexCount; i++)
         if(adjMatrix&#91;vertexIndex]&#91;i]==1 &amp;&amp; lstVertices&#91;i].visited==false)
            return i;
      return -1;
    } public void depthFirstSearch(){
      //mark first node as visited
      lstVertices&#91;0].visited = true;
      //display the vertex
      displayVertex(0);   
      //push vertex index in stack
      stack.push(0);
      while(!stack.isEmpty()){
         //get the unvisited vertex of vertex which is at top of the stack
         int unvisitedVertex = getAdjUnvisitedVertex(stack.peek());
         //no adjacent vertex found
         if(unvisitedVertex == -1){
            stack.pop();
         }else{
            lstVertices&#91;unvisitedVertex].visited = true;
            displayVertex(unvisitedVertex);
            stack.push(unvisitedVertex);
         }
      }
      //stack is empty, search is complete, reset the visited flag        
      for(int i=0;i&lt;vertexCount;i++){
         lstVertices&#91;i].visited = false;
      }        
    } public void breadthFirstSearch(){
      //mark first node as visited
      lstVertices&#91;0].visited = true;
      //display the vertex
      displayVertex(0);   
      //insert vertex index in queue
      queue.insert(0);
      int unvisitedVertex;
      while(!queue.isEmpty()){
         //get the unvisited vertex of vertex which is at front of the queue
         int tempVertex = queue.remove();            
         //no adjacent vertex found
         while((unvisitedVertex=getAdjUnvisitedVertex(tempVertex)) != -1){    
            lstVertices&#91;unvisitedVertex].visited = true;
            displayVertex(unvisitedVertex);
            queue.insert(unvisitedVertex);               
         }
      }   
      //queue is empty, search is complete, reset the visited flag        
      for(int i=0;i&lt;vertexCount;i++){
         lstVertices&#91;i].visited = false;
      }    
    } }

    Demo Program

    GraphDemo.java

    package com.tutorialspoint.datastructure;
    
    public class GraphDemo {
       public static void main(String args[]){
    
      Graph graph = new Graph();
      graph.addVertex('A');   //0
      graph.addVertex('B');   //1
      graph.addVertex('C');   //2
      graph.addVertex('D');   //3
      graph.addVertex('E');   //4
      graph.addVertex('F');   //5
      graph.addVertex('G');   //6
      /*       1  2  3   
       * 0  |--B--C--D
       * A--|
       * |
       * |     4 
       * |-----E
       * |     5  6
       * |  |--F--G
       * |--| 
       */        
      graph.addEdge(0, 1);   //AB
      graph.addEdge(1, 2);   //BC
      graph.addEdge(2, 3);   //CD
      graph.addEdge(0, 4);   //AC
      graph.addEdge(0, 5);   //AF
      graph.addEdge(5, 6);   //FG
      System.out.print("Depth First Search: ");
      //A B C D E F G
      graph.depthFirstSearch();        
      System.out.println("");
      System.out.print("Breadth First Search: ");
      //A B E F C G D
      graph.breadthFirstSearch();
    } }

    If we compile and run the above program then it would produce following result −

    Depth First Search: A B C D E F G 
    Breadth First Search: A B E F C G D
    
  • Heap

    Overview

    Heap represents a special tree based data structure used to represent priority queue or for heap sort. We’ll going to discuss binary heap tree specifically.

    Binary heap tree can be classified as a binary tree with two constraints −

    • Completeness − Binary heap tree is a complete binary tree except the last level which may not have all elements but elements from left to right should be filled in.
    • Heapness − All parent nodes should be greater or smaller to their children. If parent node is to be greater than its child then it is called Max heap otherwise it is called Min heap. Max heap is used for heap sort and Min heap is used for priority queue. We’re considering Min Heap and will use array implementation for the same.

    Basic Operations

    Following are basic primary operations of a Min heap which are following.

    • Insert − insert an element in a heap.
    • Get Minimum − get minimum element from the heap.
    • Remove Minimum − remove the minimum element from the heap

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Insert Operation

    • Whenever an element is to be inserted. Insert element at the end of the array. Increase the size of heap by 1.
    • Heap up the element while heap property is broken. Compare element with parent’s value and swap them if required.
    public void insert(int value) {            
       size++;
       intArray[size - 1] = value;
       heapUp(size - 1);
    }
    
    private void heapUp(int nodeIndex){
       int parentIndex, tmp;
       if (nodeIndex != 0) {
    
      parentIndex = getParentIndex(nodeIndex);
      if (intArray&#91;parentIndex] &gt; intArray&#91;nodeIndex]) {
         tmp = intArray&#91;parentIndex];
         intArray&#91;parentIndex] = intArray&#91;nodeIndex];
         intArray&#91;nodeIndex] = tmp;
         heapUp(parentIndex);
      }
    } }

    Get Minimum

    Get the first element of the array implementing the heap being root.

    public int getMinimum(){
       return intArray[0];
    }

    Remove Minimum

    • Whenever an element is to be removed. Get the last element of the array and reduce size of heap by 1.
    • Heap down the element while heap property is broken. Compare element with children’s value and swap them if required.
    public void removeMin() {
       intArray[0] = intArray[size - 1];
       size--;
       if (size > 0)
    
      heapDown(0);
    } private void heapDown(int nodeIndex){ int leftChildIndex, rightChildIndex, minIndex, tmp; leftChildIndex = getLeftChildIndex(nodeIndex); rightChildIndex = getRightChildIndex(nodeIndex); if (rightChildIndex >= size) {
      if (leftChildIndex &gt;= size)
         return;
      else
         minIndex = leftChildIndex;
    } else {
      if (intArray&#91;leftChildIndex] &lt;= intArray&#91;rightChildIndex])
         minIndex = leftChildIndex;
      else
         minIndex = rightChildIndex;
    } if (intArray[nodeIndex] > intArray[minIndex]) {
      tmp = intArray&#91;minIndex];
      intArray&#91;minIndex] = intArray&#91;nodeIndex];
      intArray&#91;nodeIndex] = tmp;
      heapDown(minIndex);
    } }

    Heap Implementation

    Heap.java

    package com.tutorialspoint.datastructure;
    
    public class Heap {
       private int[] intArray;
       private int size;
    
       public Heap(int size){
    
      intArray = new int&#91;size];
    } public boolean isEmpty(){
      return size == 0;
    } public int getMinimum(){
      return intArray&#91;0];
    } public int getLeftChildIndex(int nodeIndex){
      return 2*nodeIndex +1;
    } public int getRightChildIndex(int nodeIndex){
      return 2*nodeIndex +2;
    } public int getParentIndex(int nodeIndex){
      return (nodeIndex -1)/2;
    } public boolean isFull(){
      return size == intArray.length;
    } public void insert(int value) {
      size++;
      intArray&#91;size - 1] = value;
      heapUp(size - 1);
    } public void removeMin() {
      intArray&#91;0] = intArray&#91;size - 1];
      size--;
      if (size &gt; 0)
         heapDown(0);
    } /** * Heap up the new element,until heap property is broken. * Steps: * 1. Compare node's value with parent's value. * 2. Swap them, If they are in wrong order. * */ private void heapUp(int nodeIndex){
      int parentIndex, tmp;
      if (nodeIndex != 0) {
         parentIndex = getParentIndex(nodeIndex);
         if (intArray&#91;parentIndex] &gt; intArray&#91;nodeIndex]) {
            tmp = intArray&#91;parentIndex];
            intArray&#91;parentIndex] = intArray&#91;nodeIndex];
            intArray&#91;nodeIndex] = tmp;
            heapUp(parentIndex);
         }
      }
    } /** * Heap down the root element being least in value,until heap property is broken. * Steps: * 1.If current node has no children, done. * 2.If current node has one children and heap property is broken, * 3.Swap the current node and child node and heap down. * 4.If current node has one children and heap property is broken, find smaller one * 5.Swap the current node and child node and heap down. * */ private void heapDown(int nodeIndex){
      int leftChildIndex, rightChildIndex, minIndex, tmp;
      leftChildIndex = getLeftChildIndex(nodeIndex);
      rightChildIndex = getRightChildIndex(nodeIndex);
      if (rightChildIndex &gt;= size) {
         if (leftChildIndex &gt;= size)
            return;
         else
            minIndex = leftChildIndex;
      } else {
         if (intArray&#91;leftChildIndex] &lt;= intArray&#91;rightChildIndex])
            minIndex = leftChildIndex;
         else
            minIndex = rightChildIndex;
      }
      if (intArray&#91;nodeIndex] &gt; intArray&#91;minIndex]) {
         tmp = intArray&#91;minIndex];
         intArray&#91;minIndex] = intArray&#91;nodeIndex];
         intArray&#91;nodeIndex] = tmp;
         heapDown(minIndex);
      }
    } }

    Demo Program

    HeapDemo.java

    package com.tutorialspoint.datastructure;
    
    public class HeapDemo {
       public static void main(String[] args){
    
      Heap heap = new Heap(10);
       /*                     5                //Level 0
        * 
        */
      heap.insert(5);
       /*                     1                //Level 0
        *                     |
        *                 5---|                //Level 1
        */
      heap.insert(1);
       /*                     1                //Level 0
        *                     |
        *                 5---|---3            //Level 1
        */
      heap.insert(3);
       /*                     1                //Level 0
        *                     |
        *                 5---|---3            //Level 1
        *                 |
        *              8--|                    //Level 2
        */
      heap.insert(8);
      /*                     1                //Level 0
       *                     |
       *                 5---|---3            //Level 1
       *                 |
       *              8--|--9                 //Level 2
       */
      heap.insert(9);
      /*                     1                 //Level 0
       *                     |
       *                 5---|---3             //Level 1
       *                 |       |
       *              8--|--9 6--|             //Level 2
       */
      heap.insert(6);
      /*                     1                 //Level 0
       *                     |
       *                 5---|---2             //Level 1
       *                 |       |
       *              8--|--9 6--|--3          //Level 2
       */
      heap.insert(2);
      System.out.println(heap.getMinimum());
      heap.removeMin();
      /*                     2                 //Level 0
       *                     |
       *                 5---|---3             //Level 1
       *                 |       |
       *              8--|--9 6--|             //Level 2
       */
      System.out.println(heap.getMinimum());   
    } }

    If we compile and run the above program then it would produce following result −

    1
    2
    
  • Hash Table

    Overview

    HashTable is a datastructure in which insertion and search operations are very fast irrespective of size of the hashtable. It is nearly a constant or O(1). Hash Table uses array as a storage medium and uses hash technique to generate index where an element is to be inserted or to be located from.

    Hashing

    Hashing is a technique to convert a range of key values into a range of indexes of an array. We’re going to use modulo operator to get a range of key values. Consider an example of hashtable of size 20, and following items are to be stored. Item are in (key,value) format.

    • (1,20)
    • (2,70)
    • (42,80)
    • (4,25)
    • (12,44)
    • (14,32)
    • (17,11)
    • (13,78)
    • (37,98)
    Sr.No.KeyHashArray Index
    111 % 20 = 11
    222 % 20 = 22
    34242 % 20 = 22
    444 % 20 = 44
    51212 % 20 = 1212
    61414 % 20 = 1414
    71717 % 20 = 1717
    81313 % 20 = 1313
    93737 % 20 = 1717

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Linear Probing

    As we can see, it may happen that the hashing technique used create already used index of the array. In such case, we can search the next empty location in the array by looking into the next cell until we found an empty cell. This technique is called linear probing.

    Sr.No.KeyHashArray IndexAfter Linear Probing, Array Index
    111 % 20 = 111
    222 % 20 = 222
    34242 % 20 = 223
    444 % 20 = 444
    51212 % 20 = 121212
    61414 % 20 = 141414
    71717 % 20 = 171717
    81313 % 20 = 131313
    93737 % 20 = 171718

    Basic Operations

    Following are basic primary operations of a hashtable which are following.

    • Search − search an element in a hashtable.
    • Insert − insert an element in a hashtable.
    • delete − delete an element from a hashtable.

    DataItem

    Define a data item having some data, and key based on which search is to be conducted in hashtable.

    public class DataItem {
       private int key;
       private int data;
    
       public DataItem(int key, int data){
    
      this.key = key;
      this.data = data;
    } public int getKey(){
      return key;
    } public int getData(){
      return data;
    } }

    Hash Method

    Define a hashing method to compute the hash code of the key of the data item.

    public int hashCode(int key){
       return key % size;
    }

    Search Operation

    Whenever an element is to be searched. Compute the hash code of the key passed and locate the element using that hashcode as index in the array. Use linear probing to get element ahead if element not found at computed hash code.

    public DataItem search(int key){               
       //get the hash 
       int hashIndex = hashCode(key);        
       //move in array until an empty 
       while(hashArray[hashIndex] !=null){
    
      if(hashArray&#91;hashIndex].getKey() == key)
         return hashArray&#91;hashIndex]; 
      //go to next cell
      ++hashIndex;
      //wrap around the table
      hashIndex %= size;
    } return null; }

    Insert Operation

    Whenever an element is to be inserted. Compute the hash code of the key passed and locate the index using that hashcode as index in the array. Use linear probing for empty location if an element is found at computed hash code.

    public void insert(DataItem item){
       int key = item.getKey();
    
       //get the hash 
       int hashIndex = hashCode(key);
    
       //move in array until an empty or deleted cell
       while(hashArray[hashIndex] !=null
    
      &amp;&amp; hashArray&#91;hashIndex].getKey() != -1){
      //go to next cell
      ++hashIndex;
      //wrap around the table
      hashIndex %= size;
    } hashArray[hashIndex] = item; }

    Delete Operation

    Whenever an element is to be deleted. Compute the hash code of the key passed and locate the index using that hashcode as index in the array. Use linear probing to get element ahead if an element is not found at computed hash code. When found, store a dummy item there to keep performance of hashtable intact.

    public DataItem delete(DataItem item){
       int key = item.getKey();
    
       //get the hash 
       int hashIndex = hashCode(key);
    
       //move in array until an empty 
       while(hashArray[hashIndex] !=null){
    
      if(hashArray&#91;hashIndex].getKey() == key){
         DataItem temp = hashArray&#91;hashIndex]; 
         //assign a dummy item at deleted position
         hashArray&#91;hashIndex] = dummyItem; 
         return temp;
      }               
      //go to next cell
      ++hashIndex;
      //wrap around the table
      hashIndex %= size;
    } return null; }

    HashTable Implementation

    DataItem.java

    package com.tutorialspoint.datastructure;
    
    public class DataItem {
       private int key;
       private int data;
    
       public DataItem(int key, int data){
    
      this.key = key;
      this.data = data;
    } public int getKey(){
      return key;
    } public int getData(){
      return data;
    } }

    HashTable.java

    package com.tutorialspoint.datastructure;
    
    public class HashTable {
    
    private DataItem[] hashArray; private int size; private DataItem dummyItem; public HashTable(int size){
      this.size = size;
      hashArray = new DataItem&#91;size];
      dummyItem = new DataItem(-1,-1);
    } public void display(){
      for(int i=0; i&lt;size; i++) {
         if(hashArray&#91;i] != null)
            System.out.print(" ("
               +hashArray&#91;i].getKey()+","
               +hashArray&#91;i].getData() + ") ");
         else
            System.out.print(" ~~ ");
      }
      System.out.println("");
    } public int hashCode(int key){
      return key % size;
    } public DataItem search(int key){
      //get the hash 
      int hashIndex = hashCode(key);        
      //move in array until an empty 
      while(hashArray&#91;hashIndex] !=null){
         if(hashArray&#91;hashIndex].getKey() == key)
            return hashArray&#91;hashIndex]; 
         //go to next cell
         ++hashIndex;
         //wrap around the table
         hashIndex %= size;
      }        
      return null;        
    } public void insert(DataItem item){
      int key = item.getKey();
      //get the hash 
      int hashIndex = hashCode(key);
      //move in array until an empty or deleted cell
      while(hashArray&#91;hashIndex] !=null
         &amp;&amp; hashArray&#91;hashIndex].getKey() != -1){
         //go to next cell
         ++hashIndex;
         //wrap around the table
         hashIndex %= size;
      }
      hashArray&#91;hashIndex] = item;        
    } public DataItem delete(DataItem item){
      int key = item.getKey();
      //get the hash 
      int hashIndex = hashCode(key);
      //move in array until an empty 
      while(hashArray&#91;hashIndex] !=null){
         if(hashArray&#91;hashIndex].getKey() == key){
            DataItem temp = hashArray&#91;hashIndex]; 
            //assign a dummy item at deleted position
            hashArray&#91;hashIndex] = dummyItem; 
            return temp;
         }                  
         //go to next cell
         ++hashIndex;
         //wrap around the table
         hashIndex %= size;
      }        
      return null;        
    } }

    Demo Program

    HashTableDemo.java

    package com.tutorialspoint.datastructure;
    
    public class HashTableDemo {
       public static void main(String[] args){
    
      HashTable hashTable = new HashTable(20);
      hashTable.insert(new DataItem(1, 20));
      hashTable.insert(new DataItem(2, 70));
      hashTable.insert(new DataItem(42, 80));
      hashTable.insert(new DataItem(4, 25));
      hashTable.insert(new DataItem(12, 44));
      hashTable.insert(new DataItem(14, 32));
      hashTable.insert(new DataItem(17, 11));
      hashTable.insert(new DataItem(13, 78));
      hashTable.insert(new DataItem(37, 97));
      hashTable.display();
      DataItem item = hashTable.search(37);
      if(item != null){
         System.out.println("Element found: "+ item.getData());
      }else{
         System.out.println("Element not found");
      }
      hashTable.delete(item);
      item = hashTable.search(37);
      if(item != null){
         System.out.println("Element found: "+ item.getData());
      }else{
         System.out.println("Element not found");
      }
    } }

    If we compile and run the above program then it would produce following result −

     ~~  (1,20)  (2,70)  (42,80)  (4,25)  ~~  ~~  ~~  ~~  ~~  ~~  ~~ (12,44)  (13,78)  (14,32)  ~~  ~~  (17,11)  (37,97)  ~~ 
    Element found: 97
    Element not found
    
  • Tree

    Overview

    Tree represents nodes connected by edges. We’ll going to discuss binary tree or binary search tree specifically.

    Binary Tree is a special datastructure used for data storage purposes. A binary tree has a special condition that each node can have two children at maximum. A binary tree have benefits of both an ordered array and a linked list as search is as quick as in sorted array and insertion or deletion operation are as fast as in linked list.

    Terms

    Following are important terms with respect to tree.

    • Path − Path refers to sequence of nodes along the edges of a tree.
    • Root − Node at the top of the tree is called root. There is only one root per tree and one path from root node to any node.
    • Parent − Any node except root node has one edge upward to a node called parent.
    • Child − Node below a given node connected by its edge downward is called its child node.
    • Leaf − Node which does not have any child node is called leaf node.
    • Subtree − Subtree represents descendents of a node.
    • Visiting − Visiting refers to checking value of a node when control is on the node.
    • Traversing − Traversing means passing through nodes in a specific order.
    • Levels − Level of a node represents the generation of a node. If root node is at level 0, then its next child node is at level 1, its grandchild is at level 2 and so on.
    • keys − Key represents a value of a node based on which a search operation is to be carried out for a node.

    Binary Search tree exibits a special behaviour. A node’s left child must have value less than its parent’s value and node’s right child must have value greater than it’s parent value.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Binary Search Tree Representation

    We’re going to implement tree using node object and connecting them through references.

    Basic Operations

    Following are basic primary operations of a tree which are following.

    • Search − search an element in a tree.
    • Insert − insert an element in a tree.
    • Preorder Traversal − traverse a tree in a preorder manner.
    • Inorder Traversal − traverse a tree in an inorder manner.
    • Postorder Traversal − traverse a tree in a postorder manner.

    Node

    Define a node having some data, references to its left and right child nodes.

    public class Node {
       public int data;
       public Node leftChild;
       public Node rightChild;
    
       public Node(){}
    
       public void display(){
    
      System.out.print("("+data+ ")");
    } }

    Search Operation

    Whenever an element is to be search. Start search from root node then if data is less than key value, search element in left subtree otherwise search element in right subtree. Follow the same algorithm for each node.

    public Node search(int data){
       Node current = root;
       System.out.print("Visiting elements: ");
       while(current.data != data){
    
      if(current != null)
         System.out.print(current.data + " "); 
         //go to left tree
         if(current.data &gt; data){
            current = current.leftChild;
         }//else go to right tree
         else{                
            current = current.rightChild;
         }
         //not found
         if(current == null){
            return null;
         }
      }
    return current; }

    Insert Operation

    Whenever an element is to be inserted. First locate its proper location. Start search from root node then if data is less than key value, search empty location in left subtree and insert the data. Otherwise search empty location in right subtree and insert the data.

    public void insert(int data){
       Node tempNode = new Node();
       tempNode.data = data;
    
       //if tree is empty
       if(root == null){
    
      root = tempNode;
    }else{
      Node current = root;
      Node parent = null;
      while(true){                
         parent = current;
         //go to left of the tree
         if(data &lt; parent.data){
            current = current.leftChild;                
            //insert to the left
            if(current == null){
               parent.leftChild = tempNode;
               return;
            }
         }//go to right of the tree
         else{
            current = current.rightChild;
            //insert to the right
            if(current == null){
               parent.rightChild = tempNode;
               return;
            }
         }
      }            
    } }

    Preorder Traversal

    It is a simple three step process.

    • visit root node
    • traverse left subtree
    • traverse right subtree
    private void preOrder(Node root){
       if(root!=null){
    
      System.out.print(root.data + " ");
      preOrder(root.leftChild);
      preOrder(root.rightChild);
    } }

    Inorder Traversal

    It is a simple three step process.

    • traverse left subtree
    • visit root node
    • traverse right subtree
    private void inOrder(Node root){
       if(root!=null){
    
      inOrder(root.leftChild);
      System.out.print(root.data + " ");            
      inOrder(root.rightChild);
    } }

    Postorder Traversal

    It is a simple three step process.

    • traverse left subtree
    • traverse right subtree
    • visit root node
    private void postOrder(Node root){
       if(root!=null){            
    
      postOrder(root.leftChild);
      postOrder(root.rightChild);
      System.out.print(root.data + " ");
    } }

    Tree Implementation

    Node.java

    package com.tutorialspoint.datastructure;
    
    public class Node {
       public int data;
       public Node leftChild;
       public Node rightChild;
    
       public Node(){}
    
       public void display(){
    
      System.out.print("("+data+ ")");
    } }

    Tree.java

    package com.tutorialspoint.datastructure;
    
    public class Tree {
       private Node root;
    
       public Tree(){
    
      root = null;
    } public Node search(int data){
      Node current = root;
      System.out.print("Visiting elements: ");
      while(current.data != data){
         if(current != null)
            System.out.print(current.data + " "); 
            //go to left tree
            if(current.data &gt; data){
               current = current.leftChild;
            }//else go to right tree
            else{                
               current = current.rightChild;
            }
            //not found
            if(current == null){
               return null;
            }
         }
      return current;
    } public void insert(int data){
      Node tempNode = new Node();
      tempNode.data = data;
      //if tree is empty
      if(root == null){
         root = tempNode;
     }else{
         Node current = root;
         Node parent = null;
         while(true){                
            parent = current;
            //go to left of the tree
            if(data &lt; parent.data){
               current = current.leftChild;                
               //insert to the left
               if(current == null){
                  parent.leftChild = tempNode;
                  return;
               }
            }//go to right of the tree
            else{
               current = current.rightChild;
               //insert to the right
               if(current == null){
                  parent.rightChild = tempNode;
                  return;
               }
            }
         }            
      }
    } public void traverse(int traversalType){
      switch(traversalType){
         case 1:
            System.out.print("\nPreorder traversal: ");
            preOrder(root);
            break;
         case 2:
            System.out.print("\nInorder traversal: ");
            inOrder(root);
            break;
         case 3:
            System.out.print("\nPostorder traversal: ");
            postOrder(root);
            break;
         }            
    } private void preOrder(Node root){
      if(root!=null){
         System.out.print(root.data + " ");
         preOrder(root.leftChild);
         preOrder(root.rightChild);
      }
    } private void inOrder(Node root){
      if(root!=null){
         inOrder(root.leftChild);
         System.out.print(root.data + " ");            
         inOrder(root.rightChild);
      }
    } private void postOrder(Node root){
      if(root!=null){            
         postOrder(root.leftChild);
         postOrder(root.rightChild);
         System.out.print(root.data + " ");
      }
    } }

    Demo Program

    TreeDemo.java

    package com.tutorialspoint.datastructure;
    
    public class TreeDemo {
       public static void main(String[] args){
    
      Tree tree = new Tree();
      /*                     11               //Level 0
      */
      tree.insert(11);
      /*                     11               //Level 0
      *                      |
      *                      |---20           //Level 1
      */
      tree.insert(20);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      */
      tree.insert(3);        
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                           |
      *                           |--42       //Level 2
      */
      tree.insert(42);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                           |
      *                           |--42       //Level 2
      *                               |
      *                               |--54   //Level 3
      */
      tree.insert(54);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                           |
      *                       16--|--42       //Level 2
      *                               |
      *                               |--54   //Level 3
      */
      tree.insert(16);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                           |
      *                       16--|--42       //Level 2
      *                               |
      *                           32--|--54   //Level 3
      */
      tree.insert(32);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                  |        |
      *                  |--9 16--|--42       //Level 2
      *                               |
      *                           32--|--54   //Level 3
      */
      tree.insert(9);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                  |        |
      *                  |--9 16--|--42       //Level 2
      *                     |         |
      *                  4--|     32--|--54   //Level 3
      */
      tree.insert(4);
      /*                     11               //Level 0
      *                      |
      *                  3---|---20           //Level 1
      *                  |        |
      *                  |--9 16--|--42       //Level 2
      *                     |         |
      *                  4--|--10 32--|--54   //Level 3
      */
      tree.insert(10);
      Node node = tree.search(32);
      if(node!=null){
         System.out.print("Element found.");
         node.display();
         System.out.println();
      }else{
         System.out.println("Element not found.");
      }
      Node node1 = tree.search(2);
      if(node1!=null){
         System.out.println("Element found.");
         node1.display();
         System.out.println();
      }else{
         System.out.println("Element not found.");
      }        
      //pre-order traversal
      //root, left ,right
      tree.traverse(1);
      //in-order traversal
      //left, root ,right
      tree.traverse(2);
      //post order traversal
      //left, right, root
      tree.traverse(3);       
    } }

    If we compile and run the above program then it would produce following result −

    Visiting elements: 11 20 42 Element found.(32)
    Visiting elements: 11 3 Element not found.
    
    Preorder traversal: 11 3 9 4 10 20 16 42 32 54 
    Inorder traversal: 3 4 9 10 11 16 20 32 42 54 
    Postorder traversal: 4 10 9 3 16 32 54 42 20 11
    
  • Priority Queue

    Overview

    Priority Queue is more specilized data structure than Queue. Like ordinary queue, priority queue has same method but with a major difference. In Priority queue items are ordered by key value so that item with the lowest value of key is at front and item with the highest value of key is at rear or vice versa. So we’re assigned priority to item based on its key value. Lower the value, higher the priority. Following are the principal methods of a Priority Queue.

    Basic Operations

    • insert / enqueue − add an item to the rear of the queue.
    • remove / dequeue − remove an item from the front of the queue.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Priority Queue Representation

    Queue

    We’re going to implement Queue using array in this article. There is few more operations supported by queue which are following.

    • Peek − get the element at front of the queue.
    • isFull − check if queue is full.
    • isEmpty − check if queue is empty.

    Insert / Enqueue Operation

    Whenever an element is inserted into queue, priority queue inserts the item according to its order. Here we’re assuming that data with high value has low priority.

    Insert Operation
    public void insert(int data){
       int i =0;
    
       if(!isFull()){
    
      // if queue is empty, insert the data 
      if(itemCount == 0){
         intArray&#91;itemCount++] = data;        
      }else{
         // start from the right end of the queue 
         for(i = itemCount - 1; i &gt;= 0; i-- ){
            // if data is larger, shift existing item to right end 
            if(data &gt; intArray&#91;i]){
               intArray&#91;i+1] = intArray&#91;i];
            }else{
               break;
            }            
         }
         // insert the data 
         intArray&#91;i+1] = data;
         itemCount++;
      }
    } }

    Remove / Dequeue Operation

    Whenever an element is to be removed from queue, queue get the element using item count. Once element is removed. Item count is reduced by one.

    Queue Remove Operation
    public int remove(){
    
    return intArray&#91;--itemCount];
    }

    Priority Queue Implementation

    PriorityQueue.java

    package com.tutorialspoint.datastructure;
    
    public class PriorityQueue {
       private final int MAX;
       private int[] intArray;
       private int itemCount;
    
       public PriorityQueue(int size){
    
      MAX = size;
      intArray = new int&#91;MAX];     
      itemCount = 0;
    } public void insert(int data){
      int i =0;
      if(!isFull()){
         // if queue is empty, insert the data 
         if(itemCount == 0){
            intArray&#91;itemCount++] = data;        
         }else{
            // start from the right end of the queue 
            for(i = itemCount - 1; i &gt;= 0; i-- ){
               // if data is larger, shift existing item to right end 
               if(data &gt; intArray&#91;i]){
                  intArray&#91;i+1] = intArray&#91;i];
               }else{
                  break;
               }            
            }   
            // insert the data 
            intArray&#91;i+1] = data;
            itemCount++;
         }
      }
    } public int remove(){
      return intArray&#91;--itemCount];
    } public int peek(){
      return intArray&#91;itemCount - 1];
    } public boolean isEmpty(){
      return itemCount == 0;
    } public boolean isFull(){
      return itemCount == MAX;
    } public int size(){
      return itemCount;
    } }

    Demo Program

    PriorityQueueDemo.java

    package com.tutorialspoint.datastructure;
    
    public class PriorityQueueDemo {
       public static void main(String[] args){
    
      PriorityQueue queue = new PriorityQueue(6);
       
      //insert 5 items
      queue.insert(3);
      queue.insert(5);
      queue.insert(9);
      queue.insert(1);
      queue.insert(12);
      // ------------------
      // index : 0  1 2 3 4 
      // ------------------
      // queue : 12 9 5 3 1 
      queue.insert(15);
      // ---------------------
      // index : 0  1 2 3 4  5 
      // ---------------------
      // queue : 15 12 9 5 3 1 
      if(queue.isFull()){
         System.out.println("Queue is full!");   
      }
      //remove one item
      int num = queue.remove();
      System.out.println("Element removed: "+num);
      // ---------------------
      // index : 0  1  2 3 4 
      // ---------------------
      // queue : 15 12 9 5 3  
      //insert more items
      queue.insert(16);
      // ----------------------
      // index :  0  1 2 3 4  5
      // ----------------------
      // queue : 16 15 12 9 5 3
      //As queue is full, elements will not be inserted.
      queue.insert(17);
      queue.insert(18);
      // ----------------------
      // index : 0   1  2 3 4 5
      // ----------------------
      // queue : 16 15 12 9 5 3
      System.out.println("Element at front: "+queue.peek());
      System.out.println("----------------------");
      System.out.println("index : 5 4 3 2  1  0");
      System.out.println("----------------------");
      System.out.print("Queue:  ");
      while(!queue.isEmpty()){
         int n = queue.remove();           
         System.out.print(n +" ");
      }
    } }

    If we compile and run the above program then it would produce following result −

    Queue is full!
    Element removed: 1
    Element at front: 3
    ----------------------
    index : 5 4 3 2  1  0
    ----------------------
    Queue:  3 5 9 12 15 16
    
  • Queue

    Overview

    Queue is kind of data structure similar to stack with primary difference that the first item inserted is the first item to be removed (FIFO – First In First Out) where stack is based on LIFO, Last In First Out principal.

    Queue Representation

    Queue

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Basic Operations

    • insert / enqueue − add an item to the rear of the queue.
    • remove / dequeue − remove an item from the front of the queue.

    We’re going to implement Queue using array in this article. There is few more operations supported by queue which are following.

    • Peek − get the element at front of the queue.
    • isFull − check if queue is full.
    • isEmpty − check if queue is empty.

    Insert / Enqueue Operation

    Whenever an element is inserted into queue, queue increments the rear index for later use and stores that element at the rear end of the storage. If rear end reaches to the last index and it is wrapped to the bottom location. Such an arrangement is called wrap around and such queue is circular queue. This method is also termed as enqueue operation.

    Insert Operation
    public void insert(int data){
       if(!isFull()){
    
      if(rear == MAX-1){
         rear = -1;            
      }       
      
      intArray&#91;++rear] = data;
      itemCount++;
    } }

    Remove / Dequeue Operation

    Whenever an element is to be removed from queue, queue get the element using front index and increments the front index. As a wrap around arrangement, if front index is more than array’s max index, it is set to 0.

    Remove Operation
     	 	
    public int remove(){
       int data = intArray[front++];
       if(front == MAX){
    
      front = 0;
    } itemCount--; return data; }

    Queue Implementation

    Queue.java

    package com.tutorialspoint.datastructure;
    
    public class Queue {
    
    private final int MAX; private int[] intArray; private int front; private int rear; private int itemCount; public Queue(int size){
      MAX = size;
      intArray = new int&#91;MAX];
      front = 0;
      rear = -1;
      itemCount = 0;
    } public void insert(int data){
      if(!isFull()){
         if(rear == MAX-1){
            rear = -1;            
         }       
         intArray&#91;++rear] = data;
         itemCount++;
      }
    } public int remove(){
      int data = intArray&#91;front++];
      if(front == MAX){
         front = 0;
      }
      itemCount--;
      return data;  
    } public int peek(){
      return intArray&#91;front];
    } public boolean isEmpty(){
      return itemCount == 0;
    } public boolean isFull(){
      return itemCount == MAX;
    } public int size(){
      return itemCount;
    } }

    Demo Program

    QueueDemo.java

    package com.tutorialspoint.datastructure;
    
    public class QueueDemo {
       public static void main(String[] args){
    
      Queue queue = new Queue(6);
      
      //insert 5 items
      queue.insert(3);
      queue.insert(5);
      queue.insert(9);
      queue.insert(1);
      queue.insert(12);
      // front : 0
      // rear  : 4
      // ------------------
      // index : 0 1 2 3 4 
      // ------------------
      // queue : 3 5 9 1 12
      queue.insert(15);
      // front : 0
      // rear  : 5
      // ---------------------
      // index : 0 1 2 3 4  5 
      // ---------------------
      // queue : 3 5 9 1 12 15
      if(queue.isFull()){
         System.out.println("Queue is full!");   
      }
      //remove one item
      int num = queue.remove();
      System.out.println("Element removed: "+num);
      // front : 1
      // rear  : 5
      // -------------------
      // index : 1 2 3 4  5
      // -------------------
      // queue : 5 9 1 12 15
      //insert more items
      queue.insert(16);
      // front : 1
      // rear  : -1
      // ----------------------
      // index : 0  1 2 3 4  5
      // ----------------------
      // queue : 16 5 9 1 12 15
      //As queue is full, elements will not be inserted.
      queue.insert(17);
      queue.insert(18);
      // ----------------------
      // index : 0  1 2 3 4  5
      // ----------------------
      // queue : 16 5 9 1 12 15
      System.out.println("Element at front: "+queue.peek());
      System.out.println("----------------------");
      System.out.println("index : 5 4 3 2  1  0");
      System.out.println("----------------------");
      System.out.print("Queue:  ");
      while(!queue.isEmpty()){
         int n = queue.remove();            
         System.out.print(n +" ");
      }
    } }

    If we compile and run the above program then it would produce following result −

    Queue is full!
    Element removed: 3
    Element at front: 5
    ----------------------
    index : 5 4 3 2  1  0
    ----------------------
    Queue:  5 9 1 12 15 16
    
  • Parsing Expressions

    Ordinary airthmetic expressions like 2*(3*4) are easier for human mind to parse but for an algorithm it would be pretty difficult to parse such an expression. To ease this difficulty, an airthmetic expression can be parsed by an algorithm using a two step approach.

    • Transform the provided arithmetic expression to postfix notation.
    • Evaluate the postfix notation.

    Infix Notation

    Normal airthmetic expression follows Infix Notation in which operator is in between the operands. For example A+B here A is first operand, B is second operand and + is the operator acting on the two operands.

    Postfix Notation

    Postfix notation varies from normal arithmetic expression or infix notation in a way that the operator follows the operands. For example, consider the following examples

    Sr.NoInfix NotationPostfix Notation
    1A+BAB+
    2(A+B)*CAB+C*
    3A*(B+C)ABC+*
    4A/B+C/DAB/CD/+
    5(A+B)*(C+D)AB+CD+*
    6((A+B)*C)-DAB+C*D-

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Infix to PostFix Conversion

    Before looking into the way to translate Infix to postfix notation, we need to consider following basics of infix expression evaluation.

    • Evaluation of the infix expression starts from left to right.
    • Keep precedence in mind, for example * has higher precedence over +. For example
      • 2+3*4 = 2+12.
      • 2+3*4 = 14.
    • Override precedence using brackets, For example
      • (2+3)*4 = 5*4.
      • (2+3)*4= 20.

    Now let us transform a simple infix expression A+B*C into a postfix expression manually.

    StepCharacter readInfix Expressed parsed so farPostfix expression developed so farRemarks
    1AAA
    2+A+A
    3BA+BAB
    4*A+B*AB+ can not be copied as * has higher precedence.
    5CA+B*CABC
    6A+B*CABC*copy * as two operands are there B and C
    7A+B*CABC*+copy + as two operands are there BC and A

    Now let us transform the above infix expression A+B*C into a postfix expression using stack.

    StepCharacter readInfix Expressed parsed so farPostfix expression developed so farStack ContentsRemarks
    1AAA
    2+A+A+push + operator in a stack.
    3BA+BAB+
    4*A+B*AB+*Precedence of operator * is higher than +. push * operator in the stack. Otherwise, + would pop up.
    5CA+B*CABC+*
    6A+B*CABC*+No more operand, pop the * operator.
    7A+B*CABC*+Pop the + operator.

    Now let us see another example, by transforming infix expression A*(B+C) into a postfix expression using stack.

    StepCharacter readInfix Expressed parsed so farPostfix expression developed so farStack ContentsRemarks
    1AAA
    2*A*A*push * operator in a stack.
    3(A*(A*(push ( in the stack.
    4BA*(BAB*(
    5+A*(B+AB*(+push + in the stack.
    6CA*(B+CABC*(+
    7)A*(B+C)ABC+*(Pop the + operator.
    8A*(B+C)ABC+*Pop the ( operator.
    9A*(B+C)ABC+*Pop the rest of the operator(s).

    Demo program

    Now we’ll demonstrate the use of stack to convert infix expression to postfix expression and then evaluate the postfix expression.Stack.java

    package com.tutorialspoint.expression;
    
    public class Stack {
    
       private int size;           
       private int[] intArray;     
       private int top;            
    
       //Constructor
       public Stack(int size){
    
      this.size = size;           
      intArray = new int&#91;size];   
      top = -1;                   
    } //push item on the top of the stack public void push(int data) {
      if(!isFull()){
         //increment top by 1 and insert data
         intArray&#91;++top] = data;
      }else{
         System.out.println("Cannot add data. Stack is full.");
      }      
    } //pop item from the top of the stack public int pop() {
      //retrieve data and decrement the top by 1
      return intArray&#91;top--];        
    } //view the data at top of the stack public int peek() {
      //retrieve data from the top
      return intArray&#91;top];
    } //return true if stack is full public boolean isFull(){
      return (top == size-1);
    } //return true if stack is empty public boolean isEmpty(){
      return (top == -1);
    } }

    InfixToPostFix.java

    package com.tutorialspoint.expression;
    
    public class InfixToPostfix {
       private Stack stack;
       private String input = "";
       private String output = "";
    
       public InfixToPostfix(String input){
    
      this.input = input;
      stack = new Stack(input.length());
    } public String translate(){
      for(int i=0;i&lt;input.length();i++){
         char ch = input.charAt(i);
            switch(ch){
               case '+':
               case '-':
                  gotOperator(ch, 1);
                  break;
               case '*':
               case '/':
                  gotOperator(ch, 2);
                  break;
               case '(':
                  stack.push(ch);
                  break;
               case ')':
                  gotParenthesis(ch);
                  break;
               default:
                  output = output+ch;            
                  break;
          }
      }
      while(!stack.isEmpty()){
         output = output + (char)stack.pop();
      }       
      return output;
    }
      //got operator from input
      public void gotOperator(char operator, int precedence){
      while(!stack.isEmpty()){
         char prevOperator = (char)stack.pop();
         if(prevOperator == '('){
            stack.push(prevOperator);
            break;
         }else{
            int precedence1;
            if(prevOperator == '+' || prevOperator == '-'){
               precedence1 = 1;
            }else{
               precedence1 = 2;
            }
            if(precedence1 &lt; precedence){
               stack.push(Character.getNumericValue(prevOperator));
               break;                        
            }else{
               output = output + prevOperator;
            }                
         }   
      }
      stack.push(operator);
    } //got operator from input public void gotParenthesis(char parenthesis){
      while(!stack.isEmpty()){
         char ch = (char)stack.pop();
         if(ch == '('){                
            break;
         }else{
            output = output + ch;               
         }   
      }        
    } }

    PostFixParser.java

    package com.tutorialspoint.expression;
    
    public class PostFixParser {
    private Stack stack;
    private String input;
    
    public PostFixParser(String postfixExpression){
       input = postfixExpression;
       stack = new Stack(input.length());
    }
    
       public int evaluate(){
    
      char ch;
      int firstOperand;
      int secondOperand;
      int tempResult;
      for(int i=0;i&lt;input.length();i++){
         ch = input.charAt(i);
         if(ch &gt;= '0' &amp;&amp; ch &lt;= '9'){
            stack.push(Character.getNumericValue(ch));
         }else{
            firstOperand = stack.pop();
            secondOperand = stack.pop();
            switch(ch){
               case '+':
                  tempResult = firstOperand + secondOperand;
                  break;
               case '-':
                  tempResult = firstOperand - secondOperand;
                  break;
               case '*':
                  tempResult = firstOperand * secondOperand;
                  break;
               case '/':
                  tempResult = firstOperand / secondOperand;
                  break;   
               default:
                  tempResult = 0;
            }
            stack.push(tempResult);
         }
      }
      return stack.pop();
    } }

    PostFixDemo.java

    package com.tutorialspoint.expression;
    
    public class PostFixDemo {
       public static void main(String args[]){
    
      String input = "1*(2+3)";
      InfixToPostfix translator = new InfixToPostfix(input);
      String output = translator.translate();
      System.out.println("Infix expression is: " + input);
      System.out.println("Postfix expression is: " + output);
      PostFixParser parser = new PostFixParser(output);
      System.out.println("Result is: " + parser.evaluate());
    } }

    If we compile and run the above program then it would produce following result −

    Infix expression is: 1*(2+3)
    Postfix expression is: 123+*
    Result is: 5
    
  • Stack

    Overview

    Stack is kind of data structure which allows operations on data only at one end. It allows access to the last inserted data only. Stack is also called LIFO (Last In First Out) data structure and Push and Pop operations are related in such a way that only last item pushed (added to stack) can be popped (removed from the stack).

    Stack Representation

    Stack

    We’re going to implement Stack using array in this article.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Basic Operations

    Following are two primary operations of a stack which are following.

    • Push − push an element at the top of the stack.
    • Pop − pop an element from the top of the stack.

    There is few more operations supported by stack which are following.

    • Peek − get the top element of the stack.
    • isFull − check if stack is full.
    • isEmpty − check if stack is empty.

    Push Operation

    Whenever an element is pushed into stack, stack stores that element at the top of the storage and increments the top index for later use. If storage is full then an error message is usually shown.

    Push Operation
    // push item on the top of the stack 
    public void push(int data) {
    
       if(!isFull()){
    
      // increment top by 1 and insert data 
      intArray&#91;++top] = data;
    }else{
      System.out.println("Cannot add data. Stack is full.");
    } }

    Pop Operation

    Whenever an element is to be popped from stack, stack retrives the element from the top of the storage and decrements the top index for later use.

    Pop Operation
    // pop item from the top of the stack 
    public int pop() {
       // retrieve data and decrement the top by 1 
       return intArray[top--];        
    }

    Stack Implementation

    Stack.java

    package com.tutorialspoint.datastructure;
    
    public class Stack {
       private int size;           // size of the stack
       private int[] intArray;     // stack storage
       private int top;            // top of the stack
    
       // Constructor 
       public Stack(int size){
    
      this.size = size;           
      intArray = new int&#91;size];   //initialize array
      top = -1;                   //stack is initially empty
    } // Operation : Push // push item on the top of the stack public void push(int data) {
      if(!isFull()){
         // increment top by 1 and insert data 
         intArray&#91;++top] = data;
      }else{
         System.out.println("Cannot add data. Stack is full.");
      }      
    } // Operation : Pop // pop item from the top of the stack public int pop() {
      //retrieve data and decrement the top by 1
      return intArray&#91;top--];        
    } // Operation : Peek // view the data at top of the stack public int peek() {
      //retrieve data from the top
      return intArray&#91;top];
    } // Operation : isFull // return true if stack is full public boolean isFull(){
      return (top == size-1);
    } // Operation : isEmpty // return true if stack is empty public boolean isEmpty(){
      return (top == -1);
    } }

    Demo Program

    StackDemo.java

    package com.tutorialspoint.datastructure;
    
    public class StackDemo {
       public static void main (String[] args){
    
    
      // make a new stack
      Stack stack = new Stack(10);
      // push items on to the stack
      stack.push(3);
      stack.push(5);
      stack.push(9);
      stack.push(1);
      stack.push(12);
      stack.push(15);
      System.out.println("Element at top of the stack: " + stack.peek());
      System.out.println("Elements: ");
      // print stack data 
      while(!stack.isEmpty()){
         int data = stack.pop();
         System.out.println(data);
      }
             
      System.out.println("Stack full: " + stack.isFull());
      System.out.println("Stack empty: " + stack.isEmpty());
    } }

    If we compile and run the above program then it would produce following result −

    Element at top of the stack: 15
    Elements: 
    15
    12
    1
    9
    5
    3
    Stack full: false
    Stack empty: true
    
  • Circular Linked List

    Circular Linked List Basics

    Circular Linked List is a variation of Linked list in which first element points to last element and last element points to first element. Both Singly Linked List and Doubly Linked List can be made into as circular linked list

    Singly Linked List as Circular

    Singly Linked List as Circular Linked List

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Doubly Linked List as Circular

    Doubly Linked List as Circular Linked List

    As per above shown illustrations, following are the important points to be considered.

    • Last Link’next points to first link of the list in both cases of singly as well as doubly linked list.
    • First Link’s prev points to the last of the list in case of doubly linked list.

    Basic Operations

    Following are the important operations supported by a circular list.

    • insert − insert an element in the start of the list.
    • delete − insert an element from the start of the list.
    • display − display the list.

    length Operation

    Following code demonstrate insertion operation at in a circular linked list based on single linked list.

    //insert link at the first location
    public void insertFirst(int key, int data){
       //create a link
       Link link = new Link(key,data);
       if (isEmpty()) {
    
      first  = link;
      first.next = first;
    } else{
      //point it to old first node
      link.next = first;
      //point first to new first node
      first = link;
    } }

    Deletion Operation

    Following code demonstrate deletion operation at in a circular linked list based on single linked list.

    //delete link at the first location
    public Link deleteFirst(){
       //save reference to first link
       Link tempLink = first;
       //if only one link
       if(first.next == null){
    
      last = null;
    }else {
      first.next.prev = null;
    } first = first.next; //return the deleted link return tempLink; }

    Display List Operation

    Following code demonstrate display list operation in a circular linked list.

    public void display(){  
       //start from the beginning
       Link current = first;
       //navigate till the end of the list
       System.out.print("[ ");
       if(first != null){
    
      while(current.next != current){
         //print data
         current.display();
         //move to next item
         current = current.next;
         System.out.print(" ");
      }
    } System.out.print(" ]"); }

    Demo

    Link.java

    package com.tutorialspoint.list;
       
    public class CircularLinkedList {
       //this link always point to first Link 
       private Link first;
    
       // create an empty linked list 
       public CircularLinkedList(){
    
      first = null;       
    } public boolean isEmpty(){
      return first == null;
    } public int length(){
      int length = 0;
      //if list is empty
      if(first == null){
         return 0;
      }
      Link current = first.next;
      while(current != first){
         length++;
         current = current.next;   
      }
      return length;
    } //insert link at the first location public void insertFirst(int key, int data){ //create a link Link link = new Link(key,data);
      if (isEmpty()) {
         first  = link;
         first.next = first;
      }      
      else{
         //point it to old first node
         link.next = first;
         //point first to new first node
         first = link;
      }      
    } //delete first item public Link deleteFirst(){
      //save reference to first link
      Link tempLink = first;
      if(first.next == first){  
         first = null;
         return tempLink;
      }     
      //mark next to first link as first 
      first = first.next;
      //return the deleted link
      return tempLink;
    } public void display(){
      //start from the beginning
      Link current = first;
      //navigate till the end of the list
      System.out.print("&#91; ");
      if(first != null){
         while(current.next != current){
            //print data
            current.display();
            //move to next item
            current = current.next;
            System.out.print(" ");
         }
      }
      System.out.print(" ]");
    } }

    DoublyLinkedListDemo.java

    package com.tutorialspoint.list;
    
    public class CircularLinkedListDemo {
       public static void main(String args[]){
    
      CircularLinkedList list = new CircularLinkedList();
      list.insertFirst(1, 10);
      list.insertFirst(2, 20);
      list.insertFirst(3, 30);
      list.insertFirst(4, 1);
      list.insertFirst(5, 40);
      list.insertFirst(6, 56);
      System.out.print("\nOriginal List: ");  
      list.display();
      System.out.println("");  
      while(!list.isEmpty()){            
         Link temp = list.deleteFirst();
         System.out.print("Deleted value:");  
         temp.display();
         System.out.println("");
      }         
      System.out.print("List after deleting all items: ");          
      list.display();
      System.out.println("");
    } }

    If we compile and run the above program then it would produce following result −

    Original List: [ {6,56} {5,40} {4,1} {3,30} {2,20}  ]
    Deleted value:{6,56}
    Deleted value:{5,40}
    Deleted value:{4,1}
    Deleted value:{3,30}
    Deleted value:{2,20}
    Deleted value:{1,10}
    List after deleting all items: [  ]
    
  • Doubly Linked List

    Doubly Linked List Basics

    Doubly Linked List is a variation of Linked list in which navigation is possible in both ways either forward and backward easily as compared to Single Linked List. Following are important terms to understand the concepts of doubly Linked List

    • Link − Each Link of a linked list can store a data called an element.
    • Next − Each Link of a linked list contain a link to next link called Next.
    • Prev − Each Link of a linked list contain a link to previous link called Prev.
    • LinkedList − A LinkedList contains the connection link to the first Link called First and to the last link called Last.

    Doubly Linked List Representation

    Doubly Linked List

    As per above shown illustration, following are the important points to be considered.

    • Doubly LinkedList contains an link element called first and last.
    • Each Link carries a data field(s) and a Link Field called next.
    • Each Link is linked with its next link using its next link.
    • Each Link is linked with its previous link using its prev link.
    • Last Link carries a Link as null to mark the end of the list.

    Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

    Basic Operations

    Following are the basic operations supported by an list.

    • Insertion − add an element at the beginning of the list.
    • Deletion − delete an element at the beginning of the list.
    • Insert Last − add an element in the end of the list.
    • Delete Last − delete an element from the end of the list.
    • Insert After − add an element after an item of the list.
    • Delete − delete an element from the list using key.
    • Display forward − displaying complete list in forward manner.
    • Display backward − displaying complete list in backward manner.

    Insertion Operation

    Following code demonstrate insertion operation at beginning in a doubly linked list.

    //insert link at the first location
    public void insertFirst(int key, int data){
       //create a link
       Link link = new Link(key,data);
    
       if(isEmpty()){
    
      //make it the last link
      last = link;
    }else {
      //update first prev link
      first.prev = link;
    } //point it to old first link link.next = first; //point first to new first link first = link; }

    Deletion Operation

    Following code demonstrate deletion operation at beginning in a doubly linked list.

    //delete link at the first location
    public Link deleteFirst(){
       //save reference to first link
       Link tempLink = first;
       //if only one link
       if(first.next == null){
    
      last = null;
    }else {
      first.next.prev = null;
    } first = first.next; //return the deleted link return tempLink; }

    Insertion at End Operation

    Following code demonstrate insertion operation at last position in a doubly linked list.

    //insert link at the last location
    public void insertLast(int key, int data){
       //create a link
       Link link = new Link(key,data);
    
       if(isEmpty()){
    
      //make it the last link
      last = link;
    }else {
      //make link a new last link
      last.next = link;     
      //mark old last node as prev of new link
      link.prev = last;
    } //point last to new last node last = link; }

    Demo

    Link.java

    package com.tutorialspoint.list;
    
    public class Link {
       public int key;
       public int data;
       public Link next;
       public Link prev;
    
       public Link(int key, int data){
    
      this.key = key;
      this.data = data;
    } public void display(){
      System.out.print("{"+key+","+data+"}");
    } }

    DoublyLinkedList.java

    package com.tutorialspoint.list;
    
    public class DoublyLinkedList {
       
       //this link always point to first Link 
       private Link first;
       //this link always point to last Link 
       private Link last;
    
       // create an empty linked list 
       public DoublyLinkedList(){
    
      first = null;
      last = null;
    } //is list empty public boolean isEmpty(){
      return first == null;
    } //insert link at the first location public void insertFirst(int key, int data){
      //create a link
      Link link = new Link(key,data);
      if(isEmpty()){
         //make it the last link
         last = link;
      }else {
         //update first prev link
         first.prev = link;
      }
      //point it to old first link
      link.next = first;
      //point first to new first link
      first = link;
    } //insert link at the last location public void insertLast(int key, int data){
      //create a link
      Link link = new Link(key,data);
      if(isEmpty()){
         //make it the last link
         last = link;
      }else {
         //make link a new last link
         last.next = link;     
         //mark old last node as prev of new link
         link.prev = last;
      }
      //point last to new last node
      last = link;
    } //delete link at the first location public Link deleteFirst(){
      //save reference to first link
      Link tempLink = first;
      //if only one link
      if(first.next == null){
         last = null;
      }else {
         first.next.prev = null;
      }
      first = first.next;
      //return the deleted link
      return tempLink;
    } //delete link at the last location public Link deleteLast(){
      //save reference to last link
      Link tempLink = last;
      //if only one link
      if(first.next == null){
         first = null;
      }else {
         last.prev.next = null;
      }
      last = last.prev;
      //return the deleted link
      return tempLink;
    } //display the list in from first to last public void displayForward(){
      //start from the beginning
      Link current = first;
      //navigate till the end of the list
      System.out.print("&#91; ");
      while(current != null){
         //print data
         current.display();
         //move to next item
         current = current.next;
         System.out.print(" ");
      }      
      System.out.print(" ]");
    } //display the list from last to first public void displayBackward(){
      //start from the last
      Link current = last;
      //navigate till the start of the list
      System.out.print("&#91; ");
      while(current != null){
         //print data
         current.display();
         //move to next item
         current = current.prev;
         System.out.print(" ");
      }
      System.out.print(" ]");
    } //delete a link with given key public Link delete(int key){
      //start from the first link
      Link current = first;      
      //if list is empty
      if(first == null){
         return null;
      }
      //navigate through list
      while(current.key != key){
      //if it is last node
      if(current.next == null){
            return null;
         }else{           
            //move to next link
            current = current.next;             
         }
      }
      //found a match, update the link
      if(current == first) {
         //change first to point to next link
            first = current.next;
         }else {
            //bypass the current link
            current.prev.next = current.next;
         }    
         if(current == last){
            //change last to point to prev link
            last = current.prev;
         }else {
            current.next.prev = current.prev;
         }
         return current;
      }
    public boolean insertAfter(int key, int newKey, int data){
      //start from the first link
      Link current = first;      
      //if list is empty
      if(first == null){
         return false;
      }
      //navigate through list
      while(current.key != key){
         //if it is last node
         if(current.next == null){
            return false;
         }else{           
            //move to next link
            current = current.next;             
         }
      }
      Link newLink = new Link(newKey,data); 
      if(current==last) {
         newLink.next = null; 
         last = newLink; 
      }
      else {
         newLink.next = current.next;         
         current.next.prev = newLink;
      }
      newLink.prev = current; 
      current.next = newLink; 
      return true; 
    } }

    DoublyLinkedListDemo.java

    package com.tutorialspoint.list;
    
    public class DoublyLinkedListDemo {
    
    public static void main(String args&#91;]){
        DoublyLinkedList list = new DoublyLinkedList();
        
        list.insertFirst(1, 10);
        list.insertFirst(2, 20);
        list.insertFirst(3, 30);
        
        list.insertLast(4, 1);
        list.insertLast(5, 40);
        list.insertLast(6, 56);
       
        System.out.print("\nList (First to Last): ");  
        list.displayForward();
        System.out.println("");
        System.out.print("\nList (Last to first): "); 
        list.displayBackward();
        
        System.out.print("\nList , after deleting first record: ");
        list.deleteFirst();        
        list.displayForward();
        
        System.out.print("\nList , after deleting last record: ");  
        list.deleteLast();
        list.displayForward();
        
        System.out.print("\nList , insert after key(4) : ");  
        list.insertAfter(4,7, 13);
        list.displayForward();
        
        System.out.print("\nList  , after delete key(4) : ");  
        list.delete(4);
        list.displayForward();
        
    }
    }

    If we compile and run the above program then it would produce following result −

    List (First to Last): [ {3,30} {2,20} {1,10} {4,1} {5,40} {6,56}  ]
    
    List (Last to first): [ {6,56} {5,40} {4,1} {1,10} {2,20} {3,30}  ]
    List (First to Last) after deleting first record: [ {2,20} {1,10} {4,1} {5,40} {6,56}  ]
    List  (First to Last) after deleting last record: [ {2,20} {1,10} {4,1} {5,40}  ]
    List  (First to Last) insert after key(4) : [ {2,20} {1,10} {4,1} {7,13} {5,40}  ]
    List  (First to Last) after delete key(4) : [ {2,20} {1,10} {7,13} {5,40}  ]