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:
- 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];
- Implementation:
Java
class Testarray {
public static void main(String args[])
{
int a[]
= new int [ 5 ];
a[ 0 ] = 10 ;
a[ 1 ] = 20 ;
a[ 2 ] = 70 ;
a[ 3 ] = 40 ;
a[ 4 ] = 50 ;
for ( int i = 0 ; i < a.length;
i++)
System.out.println(a[i]);
}
}
|
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
a[ 0 ] = 10
a[ 1 ] = 20
a[ 2 ] = 70
a[ 3 ] = 40
a[ 4 ] = 50
for i in range ( len (a)):
print (a[i])
Testarray.main()
|
- 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:
- 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 {
class Node{
int data;
Node next;
public Node( int data) {
this .data = data;
this .next = null ;
}
}
public Node head = null ;
public Node tail = null ;
public void addNode( int data) {
Node newNode = new Node(data);
if (head == null ) {
head = newNode;
tail = newNode;
}
else {
tail.next = newNode;
tail = newNode;
}
}
public void display() {
Node current = head;
if (head == null ) {
System.out.println( "List is empty" );
return ;
}
System.out.println( "Nodes of singly linked list: " );
while (current != null ) {
System.out.print(current.data + " " );
current = current.next;
}
System.out.println();
}
public static void main(String[] args) {
SinglyLinkedList sList = new SinglyLinkedList();
sList.addNode( 1 );
sList.addNode( 2 );
sList.addNode( 3 );
sList.addNode( 4 );
sList.display();
}
}
|
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()
sList.addNode( 1 )
sList.addNode( 2 )
sList.addNode( 3 )
sList.addNode( 4 )
sList.display()
|
OutputThe 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
- 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 {
class Node{
int data;
Node previous;
Node next;
public Node( int data) {
this .data = data;
}
}
Node head, tail = null ;
public void addNode( int data) {
Node newNode = new Node(data);
if (head == null ) {
head = tail = newNode;
head.previous = null ;
tail.next = null ;
}
else {
tail.next = newNode;
newNode.previous = tail;
tail = newNode;
tail.next = null ;
}
}
public void display() {
Node current = head;
if (head == null ) {
System.out.println( "List is empty" );
return ;
}
System.out.println( "Nodes of doubly linked list: " );
while (current != null ) {
System.out.print(current.data + " " );
current = current.next;
}
}
public static void main(String[] args) {
DoublyLinkedList dList = new DoublyLinkedList();
dList.addNode( 1 );
dList.addNode( 2 );
dList.addNode( 3 );
dList.addNode( 4 );
dList.addNode( 5 );
dList.display();
}
}
|
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
class Node:
def __init__( self , data):
self .data = data
self .previous = None
self . next = None
def __init__( self ):
self .head = None
self .tail = None
def addNode( self , data):
newNode = self .Node(data)
if self .head = = None :
self .head = self .tail = newNode
self .head.previous = None
self .tail. next = None
else :
self .tail. next = newNode
newNode.previous = self .tail
self .tail = newNode
self .tail. next = None
def display( self ):
current = self .head
if self .head = = None :
print ( "List is empty" )
return
print ( "Nodes of doubly linked list: " )
while current ! = None :
print (current.data, end = " " )
current = current. next
|
OutputNodes 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
- 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[]) {
Vector<String> vec = new Vector<String>();
vec.add( "Tiger" );
vec.add( "Lion" );
vec.add( "Dog" );
vec.add( "Elephant" );
vec.addElement( "Rat" );
vec.addElement( "Cat" );
vec.addElement( "Deer" );
System.out.println( "Elements are: " +vec);
}
}
|
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
strings = [ " Welcome " , " to " , " GFG! " ]
for s in strings:
print (s, end = "")
|
OutputElements are: [Tiger, Lion, Dog, Elephant, Rat, Cat, Deer]
- Output:
Elements are: [Tiger, Lion, Dog, Elephant, Rat, Cat, Deer]
2. Output:
Welcome to GFG!
- 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
import java.util.Stack;
public class StackEmptyMethodExample
{
public static void main(String[] args)
{
Stack<Integer> stk= new Stack<>();
boolean result = stk.empty();
System.out.println( "Is the stack empty? " + result);
stk.push( 78 );
stk.push( 113 );
stk.push( 90 );
stk.push( 120 );
System.out.println( "Elements in Stack: " + stk);
result = stk.empty();
System.out.println( "Is the stack empty? " + result);
}
}
|
C++
#include <iostream>
#include <cstdlib>
using namespace std;
#define SIZE 10
class Stack
{
int *arr;
int top;
int capacity;
public :
Stack( int size = SIZE);
~Stack();
void push( int );
int pop();
int peek();
int size();
bool isEmpty();
bool isFull();
};
Stack::Stack( int size)
{
arr = new int [size];
capacity = size;
top = -1;
}
Stack::~Stack() {
delete [] arr;
}
void Stack::push( int x)
{
if (isFull())
{
cout << "Overflow\nProgram Terminated\n" ;
exit (EXIT_FAILURE);
}
cout << "Inserting " << x << endl;
arr[++top] = x;
}
int Stack::pop()
{
if (isEmpty())
{
cout << "Underflow\nProgram Terminated\n" ;
exit (EXIT_FAILURE);
}
cout << "Removing " << peek() << endl;
return arr[top--];
}
int Stack::peek()
{
if (!isEmpty()) {
return arr[top];
}
else {
exit (EXIT_FAILURE);
}
}
int Stack::size() {
return top + 1;
}
bool Stack::isEmpty() {
return top == -1;
}
bool Stack::isFull() {
return top == capacity - 1;
}
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
- Related articles:
- 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
class Queue {
private static int front, rear, capacity;
private static int queue[];
Queue( int size) {
front = rear = 0 ;
capacity = size;
queue = new int [capacity];
}
static void queueEnqueue( int item) {
if (capacity == rear) {
System.out.printf( "\nQueue is full\n" );
return ;
}
else {
queue[rear] = item;
rear++;
}
return ;
}
static void queueDequeue() {
if (front == rear) {
System.out.printf( "\nQueue is empty\n" );
return ;
}
else {
for ( int i = 0 ; i < rear - 1 ; i++) {
queue[i] = queue[i + 1 ];
}
if (rear < capacity)
queue[rear] = 0 ;
rear--;
}
return ;
}
static void queueDisplay()
{
int i;
if (front == rear) {
System.out.printf( "Queue is Empty\n" );
return ;
}
for (i = front; i < rear; i++) {
System.out.printf( " %d , " , queue[i]);
}
return ;
}
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) {
Queue q = new Queue( 4 );
System.out.println( "Initial Queue:" );
q.queueDisplay();
q.queueEnqueue( 10 );
q.queueEnqueue( 30 );
q.queueEnqueue( 50 );
q.queueEnqueue( 70 );
System.out.println( "Queue after Enqueue Operation:" );
q.queueDisplay();
q.queueFront();
q.queueEnqueue( 90 );
q.queueDisplay();
q.queueDequeue();
q.queueDequeue();
System.out.printf( "\nQueue after two dequeue operations:" );
q.queueDisplay();
q.queueFront();
}
}
|
C++
#include <cstdlib>
#include <iostream>
using namespace std;
#define SIZE 1000
class Queue {
int * arr;
int capacity;
int front;
int rear;
int count;
public :
Queue( int size = SIZE);
~Queue();
int dequeue();
void enqueue( int x);
int peek();
int size();
bool isEmpty();
bool isFull();
};
Queue::Queue( int size)
{
arr = new int [size];
capacity = size;
front = 0;
rear = -1;
count = 0;
}
Queue::~Queue() { delete [] arr; }
int Queue::dequeue()
{
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;
}
void Queue::enqueue( int item)
{
if (isFull()) {
cout << "Overflow\nProgram Terminated\n" ;
exit (EXIT_FAILURE);
}
cout << "Inserting " << item << endl;
rear = (rear + 1) % capacity;
arr[rear] = item;
count++;
}
int Queue::peek()
{
if (isEmpty()) {
cout << "Underflow\nProgram Terminated\n" ;
exit (EXIT_FAILURE);
}
return arr[front];
}
int Queue::size() { return count; }
bool Queue::isEmpty() { return (size() == 0); }
bool Queue::isFull() { return (size() == capacity); }
int main()
{
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
- Related articles:
Tree
- 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 {
public static class Node {
int data;
Node left;
Node right;
public Node( int data)
{
this .data = data;
this .left = null ;
this .right = null ;
}
}
public Node root;
public Tree() { root = null ; }
public int factorial( int num)
{
int fact = 1 ;
if (num == 0 )
return 1 ;
else {
while (num > 1 ) {
fact = fact * num;
num--;
}
return fact;
}
}
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();
System.out.println(
"Total number of possible Trees with given key: "
+ bt.numOfBST( 5 ));
}
}
|
OutputTotal number of possible Trees with given key: 42