Monday, November 18, 2024
Google search engine
HomeLanguagesJavaStatic and Dynamic data structures in Java with Examples

Static and Dynamic data structures in Java with Examples

Introduction :

In Java, a data structure is a way of organizing and storing data in memory. There are two types of data structures: static and dynamic.
Static data structures are those in which the size of the structure is fixed at compile time and cannot be changed at runtime. Examples of static data structures in Java include arrays, structs, and static tables. Since the size of these data structures is fixed, they are often used for small and simple data sets.
Dynamic data structures are those in which the size of the structure can be changed at runtime. Examples of dynamic data structures in Java include linked lists, stacks, queues, and trees. Since these data structures can grow or shrink as needed, they are often used for more complex and larger data sets.

The main advantage of dynamic data structures is their flexibility. They can grow or shrink as needed, which makes them more efficient for large data sets. On the other hand, static data structures can be more efficient for small data sets since they have a fixed size and require less overhead.

The data structure is a way of storing and organizing data efficiently such that the required operations on them can be performed efficiently concerning time as well as memory. Simply, Data Structure is used to reduce the complexity (mostly the time complexity) of the code. Data structures can be of two types:

Static Data structure

In the Static data structure, the size of the structure is fixed. The content of the data structure can be modified without changing the memory space allocated to it.

Examples of Static Data Structures:

Array

  1. An array is a container object that holds a fixed number of values of a single type. The length of an array is established when the array is created. An array is a group of like-typed variables that are referred to by a common name. Arrays in Java work differently than they do in C/C++. Syntax:
// Declaration
type var-name[];
OR
type[] var-name;

// Initialization
var-name = new type [size];
  1. Implementation: 

Java




// Java Program to illustrate how to declare, instantiate,
// initialize and print the Java array.
 
class Testarray {
    public static void main(String args[])
    {
        int a[]
            = new int[5]; // declaration and instantiation
        a[0] = 10; // initialization
        a[1] = 20;
        a[2] = 70;
        a[3] = 40;
        a[4] = 50;
        // traversing array
        for (int i = 0; i < a.length;
             i++) // length is the property of array
            System.out.println(a[i]);
    }
}
// contributed by Jatin Sharma


C++




#include <iostream>
using namespace std;
int main()
{
    int arr[3][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 2; j++) {
            cout << "Element:";
            cout << arr[i][j] << endl;
        }
    }
    return 0;
}


Python3




class Testarray:
    def main():
        a = [0] * 5 # declaration and instantiation
        a[0] = 10 # initialization
        a[1] = 20
        a[2] = 70
        a[3] = 40
        a[4] = 50
        # traversing array
        for i in range(len(a)): # len() is the function to get the length of the array
            print(a[i])
 
Testarray.main() # calling the main method of the Testarray class


Output

10
20
70
40
50
  1. Problem with above Array implementation: Once we create the Array we cannot alter the size of the array. So the size of the array is unalterable.

Dynamic Data Structure

In Dynamic data structure, the size of the structure is not fixed and can be modified during the operations performed on it. Dynamic data structures are designed to facilitate change of data structures in the run time.

 

Examples of Dynamic Data Structures:

Singly Linked List

  1. Linked Lists are linear data structures where the elements are not stored in contiguous locations and every element is a separate object with a data part and address part. The elements are linked using pointers and addresses. Each element is known as a node. Due to the dynamicity and ease of insertions and deletions, they are preferred over the arrays. 

Singly Linked list

C++




#include <iostream>
using namespace std;
struct Node {
    int data;
    struct Node* next;
};
struct Node* head = NULL;
void insert(int new_data)
{
    struct Node* new_node
        = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = head;
    head = new_node;
}
void display()
{
    struct Node* ptr;
    ptr = head;
    while (ptr != NULL) {
        cout << ptr->data << " ";
        ptr = ptr->next;
    }
}
int main()
{
    insert(3);
    insert(1);
    insert(7);
    insert(2);
    insert(9);
    cout << "The linked list is: ";
    display();
    return 0;
}


Java




public class SinglyLinkedList {   
    //Represent a node of the singly linked list   
    class Node{   
        int data;   
        Node next;   
             
        public Node(int data) {   
            this.data = data;   
            this.next = null;   
        }   
    }   
      
    //Represent the head and tail of the singly linked list   
    public Node head = null;   
    public Node tail = null;   
         
    //addNode() will add a new node to the list   
    public void addNode(int data) {   
        //Create a new node   
        Node newNode = new Node(data);   
             
        //Checks if the list is empty   
        if(head == null) {   
            //If list is empty, both head and tail will point to new node   
            head = newNode;   
            tail = newNode;   
        }   
        else {   
            //newNode will be added after tail such that tail's next will point to newNode   
            tail.next = newNode;   
            //newNode will become new tail of the list   
            tail = newNode;   
        }   
    }   
         
    //display() will display all the nodes present in the list   
    public void display() {   
        //Node current will point to head   
        Node current = head;   
             
        if(head == null) {   
            System.out.println("List is empty");   
            return;   
        }   
        System.out.println("Nodes of singly linked list: ");   
        while(current != null) {   
            //Prints each node by incrementing pointer   
            System.out.print(current.data + " ");   
            current = current.next;   
        }   
        System.out.println();   
    }   
         
    public static void main(String[] args) {   
             
        SinglyLinkedList sList = new SinglyLinkedList();   
             
        //Add nodes to the list   
        sList.addNode(1);   
        sList.addNode(2);   
        sList.addNode(3);   
        sList.addNode(4);   
             
        //Displays the nodes present in the list   
        sList.display();   
    }   
}   
// Contributed by Jatin Sharma


Python3




class SinglyLinkedList:
    class Node:
        def __init__(self, data):
            self.data = data
            self.next = None
     
    def __init__(self):
        self.head = None
        self.tail = None
         
    def addNode(self, data):
        newNode = self.Node(data)
        if self.head is None:
            self.head = newNode
            self.tail = newNode
        else:
            self.tail.next = newNode
            self.tail = newNode
     
    def display(self):
        current = self.head
        if self.head is None:
            print("List is empty")
            return
        print("Nodes of singly linked list: ")
        while current is not None:
            print(current.data, end=" ")
            current = current.next
        print()
         
if __name__ == '__main__':
    sList = SinglyLinkedList()
     
    #Add nodes to the list   
    sList.addNode(1)   
    sList.addNode(2)   
    sList.addNode(3)   
    sList.addNode(4)   
         
    #Displays the nodes present in the list   
    sList.display()


Output

The linked list is: 9 2 7 1 3 

Output 1:

The linked list is: 9 2 7 1 3 

Output 2:

Nodes of singly linked list: 
1 2 3 4 

Doubly Linked List

  1. A Doubly Linked List (DLL) contains an extra pointer, typically called the previous pointer, together with next pointer and data which are there in a singly linked list.  

Java




public class DoublyLinkedList { 
   
    //Represent a node of the doubly linked list 
   
    class Node{ 
        int data; 
        Node previous; 
        Node next; 
   
        public Node(int data) { 
            this.data = data; 
        
    
   
    //Represent the head and tail of the doubly linked list 
    Node head, tail = null
   
    //addNode() will add a node to the list 
    public void addNode(int data) { 
        //Create a new node 
        Node newNode = new Node(data); 
   
        //If list is empty 
        if(head == null) { 
            //Both head and tail will point to newNode 
            head = tail = newNode; 
            //head's previous will point to null 
            head.previous = null
            //tail's next will point to null, as it is the last node of the list 
            tail.next = null
        
        else
            //newNode will be added after tail such that tail's next will point to newNode 
            tail.next = newNode; 
            //newNode's previous will point to tail 
            newNode.previous = tail; 
            //newNode will become new tail 
            tail = newNode; 
            //As it is last node, tail's next will point to null 
            tail.next = null
        
    
   
    //display() will print out the nodes of the list 
    public void display() { 
        //Node current will point to head 
        Node current = head; 
        if(head == null) { 
            System.out.println("List is empty"); 
            return
        
        System.out.println("Nodes of doubly linked list: "); 
        while(current != null) { 
            //Prints each node by incrementing the pointer. 
   
            System.out.print(current.data + " "); 
            current = current.next; 
        
    
   
    public static void main(String[] args) { 
   
        DoublyLinkedList dList = new DoublyLinkedList(); 
        //Add nodes to the list 
        dList.addNode(1); 
        dList.addNode(2); 
        dList.addNode(3); 
        dList.addNode(4); 
        dList.addNode(5); 
   
        //Displays the nodes present in the list 
        dList.display(); 
    
//by Jatin Sharma


C++




#include <iostream>
using namespace std;
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
struct Node* head = NULL;
void insert(int newdata)
{
    struct Node* newnode
        = (struct Node*)malloc(sizeof(struct Node));
    newnode->data = newdata;
    newnode->prev = NULL;
    newnode->next = head;
    if (head != NULL)
        head->prev = newnode;
    head = newnode;
}
void display()
{
    struct Node* ptr;
    ptr = head;
    while (ptr != NULL) {
        cout << ptr->data << " ";
        ptr = ptr->next;
    }
}
int main()
{
    insert(3);
    insert(1);
    insert(7);
    insert(2);
    insert(9);
    cout << "The doubly linked list is: ";
    display();
    return 0;
}


Python3




# Represent a node of the doubly linked list
class Node:
    def __init__(self, data):
        self.data = data
        self.previous = None
        self.next = None
 
# Represent the head and tail of the doubly linked list 
def __init__(self):
    self.head = None
    self.tail = None
 
# addNode() will add a node to the list 
def addNode(self, data):
    # Create a new node
    newNode = self.Node(data)
 
    # If list is empty
    if self.head == None:
        # Both head and tail will point to newNode
        self.head = self.tail = newNode
        # head's previous will point to None
        self.head.previous = None
        # tail's next will point to None, as it is the last node of the list
        self.tail.next = None
    else:
        # newNode will be added after tail such that tail's next will point to newNode
        self.tail.next = newNode
        # newNode's previous will point to tail
        newNode.previous = self.tail
        # newNode will become new tail
        self.tail = newNode
        # As it is last node, tail's next will point to None
        self.tail.next = None
 
# display() will print out the nodes of the list 
def display(self):
    # Node current will point to head
    current = self.head
    if self.head == None:
        print("List is empty")
        return
    print("Nodes of doubly linked list: ")
    while current != None:
        # Prints each node by incrementing the pointer.
        print(current.data, end=" ")
        current = current.next


Output

Nodes of doubly linked list: 
1 2 3 4 5 

Output 1:

Nodes of doubly linked list: 
1 2 3 4 5 

Output 2:

The doubly linked list is: 9 2 7 1 3 

Vector

  1. The Vector class implements a growable array of objects. Vectors basically fall in legacy classes but now it is fully compatible with collections. Vector implements a dynamic array that means it can grow or shrink as required. Like an array, it contains components that can be accessed using an integer index. 

Java




import java.util.*; 
public class VectorExample { 
       public static void main(String args[]) { 
          //Create a vector 
          Vector<String> vec = new Vector<String>(); 
          //Adding elements using add() method of List 
          vec.add("Tiger"); 
          vec.add("Lion"); 
          vec.add("Dog"); 
          vec.add("Elephant"); 
          //Adding elements using addElement() method of Vector 
          vec.addElement("Rat"); 
          vec.addElement("Cat"); 
          vec.addElement("Deer"); 
             
          System.out.println("Elements are: "+vec); 
       
//By Jatin sharma


C++




#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
 
    vector<string> v;
 
    v.push_back(" Welcome ");
    v.push_back(" to ");
    v.push_back(" GFG! ");
 
    for (vector<string>::iterator i = v.begin();
         i != v.end(); ++i)
        cout << *i;
    return 0;
}


Python3




# create a list of strings
strings = [" Welcome ", " to ", " GFG! "]
 
# loop through the list and print each string
for s in strings:
    print(s, end="")


Output

Elements are: [Tiger, Lion, Dog, Elephant, Rat, Cat, Deer]
  1. Output:
Elements are: [Tiger, Lion, Dog, Elephant, Rat, Cat, Deer]

       2. Output:

Welcome  to  GFG!

Stack

  1. Java Collection framework provides a Stack class which models and implements a Stack data structure. The class is based on the basic principle of last-in-first-out. In addition to the basic push and pop operations, the class provides three more functions of empty, search and peek. The class can also be said to extend Vector and treats the class as a stack with the five mentioned functions. The class can also be referred to as the subclass of Vector.  

Java




// Java code for stack implementation
 
import java.util.Stack; 
public class StackEmptyMethodExample 
public static void main(String[] args)  
//creating an instance of Stack class 
Stack<Integer> stk= new Stack<>(); 
// checking stack is empty or not 
boolean result = stk.empty(); 
System.out.println("Is the stack empty? " + result); 
// pushing elements into stack 
stk.push(78); 
stk.push(113); 
stk.push(90); 
stk.push(120); 
//prints elements of the stack 
System.out.println("Elements in Stack: " + stk); 
result = stk.empty(); 
System.out.println("Is the stack empty? " + result); 
//By jatin sharma


C++




#include <iostream>
#include <cstdlib>
using namespace std;
  
// Define the default capacity of the stack
#define SIZE 10
  
// A class to represent a stack
class Stack
{
    int *arr;
    int top;
    int capacity;
  
public:
    Stack(int size = SIZE);         // constructor
    ~Stack();                       // destructor
  
    void push(int);
    int pop();
    int peek();
  
    int size();
    bool isEmpty();
    bool isFull();
};
  
// Constructor to initialize the stack
Stack::Stack(int size)
{
    arr = new int[size];
    capacity = size;
    top = -1;
}
  
// Destructor to free memory allocated to the stack
Stack::~Stack() {
    delete[] arr;
}
  
// Utility function to add an element `x` to the stack
void Stack::push(int x)
{
    if (isFull())
    {
        cout << "Overflow\nProgram Terminated\n";
        exit(EXIT_FAILURE);
    }
  
    cout << "Inserting " << x << endl;
    arr[++top] = x;
}
  
// Utility function to pop a top element from the stack
int Stack::pop()
{
    // check for stack underflow
    if (isEmpty())
    {
        cout << "Underflow\nProgram Terminated\n";
        exit(EXIT_FAILURE);
    }
  
    cout << "Removing " << peek() << endl;
  
    // decrease stack size by 1 and (optionally) return the popped element
    return arr[top--];
}
  
// Utility function to return the top element of the stack
int Stack::peek()
{
    if (!isEmpty()) {
        return arr[top];
    }
    else {
        exit(EXIT_FAILURE);
    }
}
  
// Utility function to return the size of the stack
int Stack::size() {
    return top + 1;
}
  
// Utility function to check if the stack is empty or not
bool Stack::isEmpty() {
    return top == -1;               // or return size() == 0;
}
  
// Utility function to check if the stack is full or not
bool Stack::isFull() {
    return top == capacity - 1;     // or return size() == capacity;
}
  
int main()
{
    Stack pt(3);
  
    pt.push(1);
    pt.push(2);
  
    pt.pop();
    pt.pop();
  
    pt.push(3);
  
    cout << "The top element is " << pt.peek() << endl;
    cout << "The stack size is " << pt.size() << endl;
  
    pt.pop();
  
    if (pt.isEmpty()) {
        cout << "The stack is empty\n";
    }
    else {
        cout << "The stack is not empty\n";
    }
  
    return 0;
}


Output 1:

Is the stack empty? true
Elements in Stack: [78, 113, 90, 120]
Is the stack empty? false

Output 2:

Inserting 1
Inserting 2
Removing 2
Removing 1
Inserting 3
The top element is 3
The stack size is 1
Removing 3
The stack is empty
  1. Related articles:

Queue

  1. The Queue interface is available in java.util package and extends the Collection interface. The queue collection is used to hold the elements about to be processed and provides various operations like the insertion, removal etc. It is an ordered list of objects with its use limited to insert elements at the end of the list and deleting elements from the start of list i.e. it follows the FIFO or the First-In-First-Out principle.  

Java




// Java program to demonstrate working
// of Queue interface in Java
 
class Queue {  
       
    private static int front, rear, capacity;  
    private static int queue[];  
      
    Queue(int size) {  
        front = rear = 0;  
        capacity = size;  
        queue = new int[capacity];  
    }  
      
    // insert an element into the queue 
    static void queueEnqueue(int item)  {  
        // check if the queue is full 
        if (capacity == rear) {  
            System.out.printf("\nQueue is full\n");  
            return;  
        }  
      
        // insert element at the rear  
        else {  
            queue[rear] = item;  
            rear++;  
        }  
        return;  
    }  
      
    //remove an element from the queue 
    static void queueDequeue()  {  
        // check if queue is empty  
        if (front == rear) {  
            System.out.printf("\nQueue is empty\n");  
            return;  
        }  
      
        // shift elements to the right by one place uptil rear  
        else {  
            for (int i = 0; i < rear - 1; i++) {  
                queue[i] = queue[i + 1];  
            }  
      
          
      // set queue[rear] to 0 
            if (rear < capacity)  
                queue[rear] = 0;  
      
            // decrement rear  
            rear--;  
        }  
        return;  
    }  
      
    // print queue elements  
    static void queueDisplay()  
    {  
        int i;  
        if (front == rear) {  
            System.out.printf("Queue is Empty\n");  
            return;  
        }  
      
        // traverse front to rear and print elements  
        for (i = front; i < rear; i++) {  
            System.out.printf(" %d , ", queue[i]);  
        }  
        return;  
    }  
      
    // print front of queue  
    static void queueFront()  
    {  
        if (front == rear) {  
            System.out.printf("Queue is Empty\n");  
            return;  
        }  
        System.out.printf("\nFront Element of the queue: %d", queue[front]);  
        return;  
    }  
}  
    
public class QueueArrayImplementation { 
    public static void main(String[] args) {  
        // Create a queue of capacity 4  
        Queue q = new Queue(4);  
      
        System.out.println("Initial Queue:"); 
       // print Queue elements  
        q.queueDisplay();  
      
        // inserting elements in the queue  
        q.queueEnqueue(10);  
        q.queueEnqueue(30);  
        q.queueEnqueue(50);  
        q.queueEnqueue(70);  
      
        // print Queue elements  
        System.out.println("Queue after Enqueue Operation:"); 
        q.queueDisplay();  
      
        // print front of the queue  
        q.queueFront();  
            
        // insert element in the queue  
        q.queueEnqueue(90);  
      
        // print Queue elements  
        q.queueDisplay();  
      
        q.queueDequeue();  
        q.queueDequeue();  
        System.out.printf("\nQueue after two dequeue operations:");  
      
        // print Queue elements  
        q.queueDisplay();  
      
        // print front of the queue  
        q.queueFront();  
    }  
}
//by Jatin sharma


C++




#include <cstdlib>
#include <iostream>
using namespace std;
 
// Define the default capacity of a queue
#define SIZE 1000
 
// A class to store a queue
class Queue {
    int* arr; // array to store queue elements
    int capacity; // maximum capacity of the queue
    int front; // front points to the front element in the
               // queue (if any)
    int rear; // rear points to the last element in the
              // queue
    int count; // current size of the queue
 
public:
    Queue(int size = SIZE); // constructor
    ~Queue(); // destructor
 
    int dequeue();
    void enqueue(int x);
    int peek();
    int size();
    bool isEmpty();
    bool isFull();
};
 
// Constructor to initialize a queue
Queue::Queue(int size)
{
    arr = new int[size];
    capacity = size;
    front = 0;
    rear = -1;
    count = 0;
}
 
// Destructor to free memory allocated to the queue
Queue::~Queue() { delete[] arr; }
 
// Utility function to dequeue the front element
int Queue::dequeue()
{
    // check for queue underflow
    if (isEmpty()) {
        cout << "Underflow\nProgram Terminated\n";
        exit(EXIT_FAILURE);
    }
 
    int x = arr[front];
    cout << "Removing " << x << endl;
 
    front = (front + 1) % capacity;
    count--;
 
    return x;
}
 
// Utility function to add an item to the queue
void Queue::enqueue(int item)
{
    // check for queue overflow
    if (isFull()) {
        cout << "Overflow\nProgram Terminated\n";
        exit(EXIT_FAILURE);
    }
 
    cout << "Inserting " << item << endl;
 
    rear = (rear + 1) % capacity;
    arr[rear] = item;
    count++;
}
 
// Utility function to return the front element of the queue
int Queue::peek()
{
    if (isEmpty()) {
        cout << "Underflow\nProgram Terminated\n";
        exit(EXIT_FAILURE);
    }
    return arr[front];
}
 
// Utility function to return the size of the queue
int Queue::size() { return count; }
 
// Utility function to check if the queue is empty or not
bool Queue::isEmpty() { return (size() == 0); }
 
// Utility function to check if the queue is full or not
bool Queue::isFull() { return (size() == capacity); }
 
int main()
{
    // create a queue of capacity 5
    Queue q(5);
 
    q.enqueue(1);
    q.enqueue(2);
    q.enqueue(3);
 
    cout << "The front element is " << q.peek() << endl;
    q.dequeue();
 
    q.enqueue(4);
 
    cout << "The queue size is " << q.size() << endl;
 
    q.dequeue();
    q.dequeue();
    q.dequeue();
 
    if (q.isEmpty()) {
        cout << "The queue is empty\n";
    }
    else {
        cout << "The queue is not empty\n";
    }
 
    return 0;
}


Output1:

Initial Queue:
Queue is Empty
Queue after Enqueue Operation:
10 ,  30 ,  50 ,  70 , 
Front Element of the queue: 10
Queue is full
10 ,  30 ,  50 ,  70 , 
Queue after two dequeue operations: 50 ,  70 , 
Front Element of the queue: 50

Output2:

Inserting 1
Inserting 2
Inserting 3
The front element is 1
Removing 1
Inserting 4
The queue size is 3
Removing 2
Removing 3
Removing 4
The queue is empty
  1. Related articles:

 Tree

  1. A Tree is a data structure that stores values inside entities called Nodes. Nodes are connected through lines referred to as edges. Each node stores a value inside it. Terminology: 
    • Root is the topmost node of the tree.
    • Parent is a node that has one or more Nodes attached to it.
    • Edge is the link joining the two nodes.
    • Child is a node that has a parent node
    • Leaf is a node that doesn’t have any child node attached to it, it is the bottommost node of a tree.

Java




public class Tree {
    // Represent the node of tree
    public static class Node {
        int data;
        Node left;
        Node right;
        public Node(int data)
        {
            // Assign data to the new node, set left and
            // right children to null
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }
    // Represent the root of binary tree
    public Node root;
    public Tree() { root = null; }
    // factorial() will calculate the factorial of given
    // number
    public int factorial(int num)
    {
        int fact = 1;
        if (num == 0)
            return 1;
        else {
            while (num > 1) {
                fact = fact * num;
                num--;
            }
            return fact;
        }
    }
    // numOfBST() will calculate the total number of
    // possible BST by calculating Catalan Number for given
    // key
    public int numOfBST(int key)
    {
        int catalanNumber
            = factorial(2 * key)
              / (factorial(key + 1) * factorial(key));
        return catalanNumber;
    }
    public static void main(String[] args)
    {
       Tree bt = new Tree();
        // Display total number of possible
        // tree with key 5
        System.out.println(
            "Total number of possible Trees with given key: "
            + bt.numOfBST(5));
    }
}
// by jatin sharma


Output

Total number of possible Trees with given key: 42

RELATED ARTICLES

Most Popular

Recent Comments