Data Structure
Data Structure
DATA STRUCTURES
Data Structure is a way to store and organize data so that it can be used efficiently. There are two
types of data structures: - Linear and Non – linear data structures.
Linear Data Structures: - It refers to the sequential allocation of the data. Stack, Queue and
Linked List are those linear data structures.
Non-Linear Data Structures: - It refers to the non-sequential allocation of the data. Binary
tree is that non-linear data structures.
if (top < 0)
{
System.out.println("Stack Underflow");
return 0;
}
else
{
//System.out.println("Pop Item : " + item[top]);
return item[top--];
}
}
void display()
{
System.out.println("The items in stack");
for ( int i = top ; i>=0; i--)
{
System.out.println(item[i]);
}
}
}
import java.io.*;
class StackExample
{
public static void main(String[] args) throws IOException
{
Stack stk = new Stack(5);
boolean yes=true;
int ch;
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
do
{
System.out.println("1).Push\n2).Pop\n3).Exit\n\nEnter Choice");
ch = Integer.parseInt(is.readLine());
switch(ch)
{
case 1: System.out.println("Enter Push Item: ");
stk.pushItem(Integer.parseInt(is.readLine()));
stk.display();
break;
case 2: stk.popItem();
stk.display();
break;
case 3: yes = false;
break;
default: System.out.println("Invalid Choice");
}
}
while(yes==true);
}
}
front = 0;
Q[++rear]=v;
}
else
{
Q[++rear]=v;
}
}
int delete()
{
int del=0;
if(front==-1 && rear ==-1)
{
System.out.println("\nQueue Underflow\n");
}
else if(front == rear)
{
del = Q[front];
front = -1;
rear = -1;
}
else
{
del= Q[front];
front++;
}
return(del);
}
void show()
{
System.out.println("\nQueue Values:-");
if(front!=-1)
{
for(int i=rear;i>=front;i--)
{
System.out.println(Q[i]);
}
}
}
}
import java.util.*;
class queueOperation
{
public static void main()
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the size of the stack");
int n =sc.nextInt();
Queue q= new Queue(n);
do{
System.out.println("\nOperations on stack");
System.out.println("1.Insert value in Queue");
System.out.println("2.Delete value from Queue");
System.out.println("3.Display values of Queue");
System.out.println("4.Exit");
System.out.println("Enter the your choice");
int ch = sc.nextInt();
switch(ch)
{
case 1:
System.out.println("Enter the value");
int i=sc.nextInt();
q.insert(i);
q.show();
break;
case 2:
int d=q.delete();
System.out.println("The deleted value is " + d);
q.show();
break;
case 3:
q.show();
break;
case 4:
System.exit(0);
default:
System.out.println("Wrong choice");
}
} while(true);
}
}
Applications of the Queue
QUEUE is used when things don’t have to be processed immediately, but have to be
processed in First In First Out order. This property of Queue makes it also useful in
following kind of scenarios.
a. When a resource is shared among multiple consumers. Examples include CPU
scheduling, Disk Scheduling.
b. When data is transferred asynchronously (data not necessarily received at same rate as
sent) between two processes. Examples include IO Buffers, pipes, file IO, etc.
CIRCULAR QUEUE
A Circular Queue is a linear data structure in which the operations are performed based on FIFO
(First In First Out) principle and the last position is connected back to the first position to make a
circle. It is also known as ring buffer, circle buffer.
Characteristics of a Circular Queue
First In First Out (FIFO) principle.
The last position connects back to the first position (circular).
Uses two pointers:
front – points to the front element.
rear – points to the last element.
The formula to increment the front and rear pointers to make them go round and round over and again
will be, front = (front + 1) % size or rear = (rear + 1) % size.
/* Implementation of Circular Queue using array */
class CQueue
{
int a[];
int front, rear;
int size;
CQueue(int s)
{
size = s;
a = new int[size];
front = rear = -1;
}
boolean empty()
{
if(front == -1)
return true;
else
return false;
}
void destroy()
{
front = rear=-1;
}
void insert(int x)
{
int p;
p = (rear+1)% size;
if(p == front)
System.out.println("Queue Overflow ");
else
{
rear = p;
a[rear] = x;
if(front == -1)
front = 0;
}
}
int delete()
{
int x = a[front];
if(front == rear)
front = rear = -1;
else
front =(front+1)% a.length;
return x;
}
void display()
{
if(front == -1)
System.out.println("Queue underflow");
else
{
System.out.println("Elements of Queue are");
int i = front;
while(i != rear)
{
System.out.println(a[i]);
i = (i+1)% a.length;
}
System.out.println(a[i]);
}
}
}// End of Queue class
import java.util.Scanner;
class CircularQueue
{
public static void main(String args[])
{
Scanner sc =new Scanner(System.in);
System.out.print("Enter the size of the queue : ");
int size = sc.nextInt();
CQueue q = new CQueue(size);
int ch;
do
{
System.out.println("Menu\n1.Insert\n2.Delete\n3.display\n4.destroy\n5.exit\n");
System.out.println("Enter choice :");
ch=sc.nextInt();
switch(ch)
{
case 1:
System.out.println("Enter data to insert");
int x=sc.nextInt();
q.insert(x);
break;
case 2:
if(q.empty())
System.out.println("Queue underflow");
else
{
int z =q.delete();
System.out.println("data deleted =" + z );
}
break;
case 3:
q.display();
break;
case 4:
q.destroy();
break;
case 5:
System.exit(0);
default :
System.out.println("Wrong Choice");
}
}while(true);
}//end main
}//end CircularQueue
DEQUE
The Deque is a double-ended queue. It helps in adding and removing data elements from a data
structure from either front or rear. It can be used either as a FIFO or a LIFO. Examples of FIFO
and LIFO are Queue and Stack respectively.
Operations On Deque:
Mainly the following four basic operations are performed on queue:
insertFront(): Adds an item at the front of Deque.
insertRear(): Adds an item at the rear of Deque.
deleteFront(): Deletes an item from front of Deque.
deleteRear(): Deletes an item from rear of Deque.
f=f-1;
dq[f]=n;
}
}
void popFront()
{
int d;
if(f==-1)
System.out.println("Deque is empty");
else
{
d=dq[f];
System.out.println(d+"is popped");
if(f==r)
f=r=-1;
else
f=f+1;
}
}
void popRear()
{
int d;
if(f==-1)
System.out.println("DQ is empty");
else
{
d=dq[r];
System.out.println(d+"is popped");
if(f==r)
f=r=-1;
else
r=r-1;
}
}
void display()
{
System.out.println("The Deque is:");
for(int i=f;i<=r;i++)
System.out.println(dq[i]);
}
public static void main()
{
Scanner in=new Scanner(System.in);
System.out.println("Enter capacity");
Deque d=new Deque(in.nextInt());
int c;
do
{
System.out.println("MENU\n1)Insert at front\n2)Insert at rear\n3)Delete at front\n4)Delete at
rear\n5)Display\n6)Exit");
System.out.println("Enter your choice:");
c=in.nextInt();
switch(c)
{
case 1:
System.out.println("Enter item:");
d.pushAtFront(in.nextInt());
break;
case 2:
System.out.println("Enter item:");
d.pushAtRear(in.nextInt());
break;
case 3:
d.popFront();
break;
case 4:
d.popRear();
break;
case 5:
d.display();
break;
case 6:
System.exit(0);
default:
System.out.println(" Wrong Choice");
}
}
while(true);
}
}
Applications of Deque
Undo/Redo Functionality
Job Scheduling in OS (Multi-level Queue)
Cache Implementation (LRU Cache)
The linked list is a linear data structure that contains a sequence of elements such that each element
links to its next element in the sequence. Each element in a linked list is called "Node". A node
contains two fields i.e. data stored at that particular address and the pointer which contains the
address of the next node in the memory. The last node of the list contains pointer to the null.
Drawbacks: -
Random access is not allowed. We have to access elements sequentially starting from the
first node. So we cannot do binary search with linked lists efficiently with its default
implementation.
Extra memory space for a pointer is required with each element of the list.
Not cache friendly. Since array elements are contiguous locations, there is locality of
reference which is not there in case of linked lists.
Insert at end
Insert at position
Deletion
Delete at position
Display
Count of node
// Default Constructor
public Node()
{
Link = null;
data = 0;
}
// Parameterized Constructor
public Node(int d,Node n)
{
data = d;
Link = n;
}
}
// Class linkedList
class linkedList
{
Node start;
Node end ;
public int size ;
// Constructor
public linkedList()
{
start = null;
end = null;
size = 0;
}
// Function to insert an element at begining
public void insertAtStart(int val)
{
Node nptr = new Node(val, null);
size++ ;
if(start == null)
{
start = nptr;
end = start;
}
else
{
nptr.Link=start;
start = nptr;
}
}
// Function to insert an element at end
public void insertAtEnd(int val)
{
Node nptr = new Node(val,null);
size++ ;
if(start == null)
{
start = nptr;
end = start;
}
else
{
end.Link = nptr;
end = nptr;
}
}
// Function to insert an element at position
public void insertAtPos(int val , int pos)
{
Node nptr = new Node(val, null);
Node ptr = start;
pos = pos - 1 ;
for (int i = 1; i < size; i++)
{
if (i == pos)
{
Node tmp = ptr.Link ;
ptr.Link = nptr;
nptr.Link = tmp;
break;
}
ptr = ptr.Link;
}
size++ ;
}
//Function to delete an element at position
public void deleteAtPos(int pos)
{
if (pos == 1)
{
start = start.Link;
size--;
}
else if (pos == size)
{
Node s = start;
Node t = start;
while (s != end)
{
t = s;
s = s.Link;
}
end = t;
end.Link = null;
size --;
}
else
{
Node ptr = start;
pos = pos - 1 ;
for (int i = 1; i < size - 1; i++)
{
if (i == pos)
{
Node tmp = ptr.Link;
tmp = tmp.Link;
ptr.Link = tmp;
break;
}
ptr = ptr.Link;
}
}
size-- ;
}
// Function to display elements
public void display()
{
System.out.print("\nSingly Linked List = ");
if (size == 0)
{
System.out.println("empty\n");
}
else if (start.Link == null)
{
System.out.println(start.data);
}
else
{
Node ptr = start;
System.out.print(start.data + "->");
ptr = start.Link;
while (ptr.Link != null)
{
System.out.print(ptr.data + "->");
ptr = ptr.Link;
}
System.out.print(ptr.data + "\n");
}
}
/* Class SinglyLinkedList */
public class SinglyLinkedList
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
//Creating object of class linkedList
linkedList list = new linkedList();
System.out.println("Singly Linked List Test\n");
char ch;
// Perform list operations
do
{
System.out.println("\nSingly Linked List Operations\n");
System.out.println("1. insert at begining");
System.out.println("2. insert at end");
System.out.println("3. insert at position");
System.out.println("4. delete at position");
System.out.println("5. count");
list.display();
System.out.println("\nDo you want to continue (Type y or n) \n");
ch = scan.next().charAt(0);
} while (ch == 'Y'|| ch == 'y');
}
}
Application of Singly Linked List
Dynamic Memory Allocation
Stacks and Queues Implementation
Symbol Table or Hash Table Collision Resolution
Polynomial Arithmetic
Sparse Matrices Representation
BINARY TREE
A binary tree is a hierarchical data structure in which each node has at most two children
generally referred as left child and right child.
Root: Topmost node in a tree. From the above figure, A is the root node of the tree.
Parent: Every node (excluding a root) in a tree is connected by a directed edge from
exactly one other node. This node is called a parent. From the above figure, B, C, E
and G are parent node of the tree.
Child: A node directly connected to another node when moving away from the root.
Subtree: Any part of the tree which follows the property of the tree is known as
Subtree of the tree.
Leaf/External node: Node with no children. From the above figure, D, H, I, F and J
are leaf node of the tree.
Internal node: Node with atleast one children. From the above figure, B, C, E and G
are internal node of the tree.
Sibling: A node is said to be sibling of another node only if both the node have same
parents. From the above figure, B and C, D and E, F and G, H and I are siblings of
the tree.
Depth of a node: Number of edges from root to the node. From the above figure, the
depth of E is 2.
Height of a node: Number of edges from the node to the deepest leaf. Height of the
tree is the height of the root. From the above, the Height of the tree is 3 and Height of
node E is 1.
Level: The level of a node is defined by 1 + the number of connections between the
node and the root i.e. level = depth + 1
Degree of the node: The degree of a node is the number of children of that node. In
this case, root node has 2 children. So, the degree of root node of 2.
Degree of the tree: The maximum degree of any node is called the degree of a tree.
In this case, root node has the maximum degree 2. So, the degree of tree is 2.
Traversal of Binary Tree
Traversal is a process to visit all the nodes of a tree and may print their values too. Because,
all nodes are connected via edges (links) it always start from the root (head) node. That is,
any node of the tree cannot be accessed randomly. There are three ways which are used to
traverse a tree:-
Pre-order Traversal: - Traverse the root first then traverse into the left sub-tree and
right sub-tree respectively. This procedure will be applied to each sub-tree of the tree
recursively.
In-order Traversal: - Traverse the left sub-tree first, and then traverse the root and the right
sub-tree respectively. This procedure will be applied to each sub-tree of the tree recursively.
In order traversal: - A, B, C, D, E, F, G, H, I
Post-order Traversal: - Traverse the left sub-tree and then traverse the right sub-tree
and root respectively. This procedure will be applied to each sub-tree of the tree
recursively.