Mtech Adsa Unit2
Mtech Adsa Unit2
STACK
A linear data structure called a stack is used to store an ordered, linear sequence of elements.
It is a type of abstract data. A stack operates according to the Last In First Out (LIFO)
principle, which states that the element that was added last will be deleted first. Because we
can only access the elements on the top of the Stack, it is necessary to maintain a pointer to
the top of the Stack, which is the last element to be placed, in order to implement the Stack.
Stack Operation:
1. PUSH: The insertion of a new element into a stack is implied by the PUSH operation. The
top of the stack is always where a new element is added, so we must always check to see if it
is empty by using the formula TOP=Max-1. In the case that this condition is false, the Stack is
full and no other elements may be added. Even if we attempt to add the element, a Stack
overflow message will be shown.
Algorithm:
Step-1: If TOP = Max-1
Print “Overflow”
Goto Step 4
Step-2: Set TOP= TOP + 1
Step-3: Set Stack[TOP]= ELEMENT
Step-4: END
2. POP: POP denotes removing a stack element. Make sure to verify that the Stack Top is
NULL, i.e., TOP=NULL, before deleting an element. In the event that this condition is met,
the Stack will be empty, making deletion operations impossible. Even if deletion attempts are
made, the Stack Underflow warning will be produced.
Algorithm:
Step-1: If TOP= NULL
Print “Underflow”
Goto Step 4
Step-2: Set VAL= Stack[TOP]
Step-3: Set TOP= TOP-1
Step-4: END
3. PEEK: The Peek operation is employed when it is necessary to return the value of the
topmost stack element without erasing it. This operation first determines whether the Stack is
empty, i.e., TOP = NULL; if it is, then the value will be returned; otherwise, an appropriate
notice will be displayed.
Algorithm:
Step-1: If TOP = NULL
PRINT “Stack is Empty”
Goto Step 3
Step-2: Return Stack[TOP]
Step-3: END
Representation of the Stack
A stack may have a set, predetermined size or it may be dynamic, meaning that the size of the
stack may fluctuate over time. Pointer, Array, Structure, and Linked List can all be used to
represent it.
Application of Stack in Data Structure are as following:
Evaluation of Arithmetic Expressions
Backtracking
Delimiter Checking
Reverse a Data
Processing Function Calls
1. Evaluation of Arithmetic Expressions
In computer languages, a stack is an extremely efficient data structure for evaluating
arithmetic statements. Operands and operators are the components of an arithmetic
expression.
The arithmetic expression may additionally contain parenthesis such as "left parenthesis" and
"right parenthesis," in addition to operands and operators.
Example: A + (B – C)
The normal precedence rules for arithmetic expressions must be understood in order to
evaluate the expressions. The following are the five fundamental arithmetic operators’
precedence rules:
+ addition, –
Left to right lowest
subtraction
Here are the steps of the algorithm to convert Infix to postfix using stack in C:
Scan all the symbols one by one from left to right in the given Infix Expression.
If the reading symbol is an operand, then immediately append it to the Postfix Expression.
If the reading symbol is left parenthesis ‘( ‘, then Push it onto the Stack.
If the reading symbol is right parenthesis ‘)’, then Pop all the contents of the stack until the
respective left parenthesis is popped and append each popped symbol to Postfix Expression.
If the reading symbol is an operator (+, –, *, /), then Push it onto the Stack. However, first,
pop the operators which are already on the stack that have higher or equal precedence than the
current operator and append them to the postfix. If an open parenthesis is there on top of the
stack then push the operator into the stack.
If the input is over, pop all the remaining symbols from the stack and append them to the
postfix.
Output
Queue: [apple, banana, cherry]
Removed element: apple
Queue after removal: [banana, cherry]
Peeked element: banana
Queue after peek: [banana, cherry, date]
In a normal Queue, we can insert elements until queue becomes full. But once queue becomes full, we
can not insert the next element even if there is a space in front of queue.
Operations on Circular Queue:
Front: Get the front item from the queue.
Rear: Get the last item from the queue.
enQueue(value) This function is used to insert an element into the circular queue. In a
circular queue, the new element is always inserted at the rear position.
o Check whether the queue is full – [i.e., the rear end is in just before the front end in a
circular manner].
o If it is full then display Queue is full.
o If the queue is not full then, insert an element at the end of the queue.
deQueue() This function is used to delete an element from the circular queue. In a circular
queue, the element is always deleted from the front position.
o Check whether the queue is Empty.
o If it is empty then display Queue is empty.
o If the queue is not empty, then get the last element and remove it from the
queue.
Illustration of Circular Queue Operations:
Follow the below image for a better understanding of the enqueue and dequeue operations.
// Main.java
public class Main {
public static void main(String[] args) {
CircularQueue cq = new CircularQueue(5); // Create a queue with capacity of 5
Output:
Enqueued: 10
Enqueued: 20
Enqueued: 30
Enqueued: 40
Enqueued: 50
Queue elements:
10 20 30 40 50
Queue is full. Cannot enqueue.
Dequeued: 10
Dequeued: 20
Queue elements:
30 40 50
Enqueued: 60
Enqueued: 70
Queue elements:
30 40 50 60 70
Size of queue: 5
Front element: 30
The priority queue supports only comparable elements, which means that the elements are either
arranged in an ascending or descending order.
For example, suppose we have some values like 1, 3, 4, 8, 14, 22 inserted in a priority queue with
an ordering imposed on the values is from least to the greatest. Therefore, the 1 number would be
having the highest priority while 22 will be having the lowest priority.
1, 3, 4, 8, 14, 22
All the values are arranged in ascending order. Now, we will observe how the priority queue will
look after performing the following operations:
poll(): This function will remove the highest priority element from the priority queue. In the
above priority queue, the '1' element has the highest priority, so it will be removed from the
priority queue.
5. add(2): This function will insert '2' element in a priority queue. As 2 is the smallest element
among all the numbers so it will obtain the highest priority.
6. poll(): It will remove '2' element from the priority queue as it has the highest priority queue.
7. add(5): It will insert 5 element after 4 as 5 is larger than 4 and lesser than 8, so it will obtain
the third highest priority in a priority queue.
11. Descending order priority queue: In descending order priority queue, a higher priority
number is given as a higher priority in a priority. For example, we take the numbers from 1 to
5 arranged in descending order like 5, 4, 3, 2, 1; therefore, the largest number, i.e., 5 is given
as the highest priority in a priority queue.
13. Now, we will see how to represent the priority queue through a one-way list.
14. Advertisement
15. We will create the priority queue by using the list given below in which INFO list contains
the data elements, PRN list contains the priority numbers of each data element available in
the INFO list, and LINK basically contains the address of the next node.
16.
A priority queue can be implemented using a Max Heap (for a max-priority queue), where the
highest priority element (the largest value) is at the root.
Operations on Max Heap:
1. Insertion: Add a new element to the heap and restore the heap property (i.e., the max-heap
property).
2. Deletion: Remove the element with the highest priority (the root) and restore the heap
property.
Max Heap Implementation
In this implementation, we will use a Max Heap to implement the priority queue. The heap will be
represented as an array, where the parent-child relationships are determined by the indices of the
array.
Left child of node at index i: 2 * i + 1
Right child of node at index i: 2 * i + 2
Parent of node at index i: (i - 1) / 2
1. Max Heap Class
Here is the implementation of the Max Heap with the insertion and deletion operations:
java
Copy code
class MaxHeap {
private int[] heap;
private int size;
private int capacity;
return max;
}
V. ARRAY LIST
The java.util.ArrayList class in Java is part of the Java Collections Framework and provides a
dynamic array that can grow as needed. It is widely used for storing and manipulating lists of objects.
The ArrayList class implements the List interface and allows for efficient random access to elements,
as well as insertion and deletion operations.
Key Features of ArrayList:
1. Dynamic Size: Unlike arrays, which have a fixed size, an ArrayList can grow or shrink as
elements are added or removed.
2. Index-based Access: Elements in an ArrayList can be accessed using an index, similar to
arrays.
3. Resizing: As elements are added, the ArrayList automatically resizes its internal array to
accommodate more elements.
4. Allows Duplicates: Like most List implementations, ArrayList allows duplicate elements.
5. Order is Preserved: The order of elements in an ArrayList is maintained based on the order
in which they were added.
6. Null Values: ArrayList allows the insertion of null values (though this is not recommended in
certain contexts).
Common Methods in ArrayList:
add(E e): Adds the specified element to the end of the list.
add(int index, E element): Inserts the specified element at the specified position in the list.
remove(int index): Removes the element at the specified position in the list.
remove(Object o): Removes the first occurrence of the specified element from the list.
get(int index): Returns the element at the specified position in the list.
set(int index, E element): Replaces the element at the specified position with the specified
element.
size(): Returns the number of elements in the list.
isEmpty(): Checks if the list is empty.
contains(Object o): Returns true if the list contains the specified element.
clear(): Removes all elements from the list.
Example: Basic Usage of ArrayList
Here's an example demonstrating the creation and basic operations of an ArrayList in Java:
java
Copy code
import java.util.ArrayList;
VI. Vector
The java.util.Vector class in Java is part of the Java Collections Framework and represents a
growable array of objects. It's similar to an ArrayList but with some differences in terms of internal
implementation and behavior. A Vector is a dynamic array that can automatically resize itself when
elements are added or removed.
Key Characteristics of Vector:
1. Resizable Array: A Vector grows dynamically as more elements are added to it. Initially, a
Vector has a default size, and it increases its capacity as needed (usually doubling its size).
2. Thread-Safety: Unlike ArrayList, the methods in Vector are synchronized, which means it is
thread-safe. However, this can lead to performance issues in multi-threaded environments
where thread-safety is not needed.
3. Can hold any type of object: Since Vector is a generic container, it can hold any type of
objects, such as Integer, String, Object, etc.
The size() method gives the number of elements currently in the Vector.
import java.util.Vector;
Sample Output:
Initial Vector: [Apple, Banana, Cherry, Date]
First element: Apple
Second element: Banana
After modification: [Apple, Banana, Orange, Date]
After removing 'Banana': [Apple, Orange, Date]
Iterating through the Vector:
Apple
Orange
Date
Vector contains 'Apple'
Size of the Vector: 3
Key Points: