0% found this document useful (0 votes)
29 views

DATA STRUCTURES AND ALGORITHMS Unit II 2024 REGULATION

This document provides an overview of linear data structures, specifically focusing on stacks, queues, and linked lists. It details the operations, applications, and algorithms associated with stacks and queues, including expression evaluation and conversion between infix, prefix, and postfix notations. Additionally, it discusses the types of queues and their implementations, highlighting the FIFO principle and various queue types such as simple, circular, and priority queues.

Uploaded by

praveen
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

DATA STRUCTURES AND ALGORITHMS Unit II 2024 REGULATION

This document provides an overview of linear data structures, specifically focusing on stacks, queues, and linked lists. It details the operations, applications, and algorithms associated with stacks and queues, including expression evaluation and conversion between infix, prefix, and postfix notations. Additionally, it discusses the types of queues and their implementations, highlighting the FIFO principle and various queue types such as simple, circular, and priority queues.

Uploaded by

praveen
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

Unit II

LINEAR DATA STRUCTURES – STACKS, QUEUES,


LISTS

Stack ADT – Operations- Applications- Evaluating


arithmetic expressions- conversion infix to postfix
expression- Queue ADT – Operations- Types of queues-
Applications of Queues- Linked List ADT: Operations of
Lists –Types of Linked List- Applications.
Stack ADT:

 A Stack is a linear data structure where insertion and deletion of items takes
place at one end called top of the stack. A Stack is defined as a data structure
which operates on a last-in first-out basis.
 So it is also is referred as Last-inFirst-out( LIFO). Stack uses a single index
or pointer to keep track of the information in the stack.

The basic operations associated with the stack are:

a) push(insert) an item onto the stack.

b) pop(remove) an item from the stack.

The general terminology associated with the stack is as follows:

 A stack pointer keeps track of the current position on the stack. When an
element is placed on the stack, it is said to be pushed on the stack.
 When an object is removed from the stack, it is said to be popped off the
stack. Two additional terms almost always used with stacks are overflow,
which occurs when we try to push more information on a stack that it can
hold, and underflow, which occurs when we try to pop an item off a stack
which is empty.

Pushing items onto the stack:

Code to push an element on to stack;

template <class t>

void stack::push()

if(top==max-1) cout<<"Stack Overflow...\n";

else { }

cout<<"Enter an element to be pushed:";

top++;

cin>>data;
stk[top]=data;

cout<<"Pushed Sucesfully....\n"

Popping an element from stack:

To remove an item, first extract the data from top position in the stack and then
decrement the stack pointer, top.

code to remove an element from stack :

template<class T>

void stack::pop()

if(top= =-1)

cout<<"Stack is Underflow";

else { }

data=stk[top];

top--;

cout<<data<<" is poped Sucesfully ....\n"


Stack Operations

A stack is a linear data structure that follows the Last-In-First-Out


(LIFO) principle. This means that the last element added to the stack is the first
one to be removed.

The following are some common operations implemented on the stack:

o push(): When we insert an element in a stack then the operation is known as


a push. If the stack is full then the overflow condition occurs.
o pop(): When we delete an element from the stack, the operation is known as
a pop. If the stack is empty means that no element exists in the stack, this
state is known as an underflow state.
o isEmpty(): It determines whether the stack is empty or not.
o isFull(): It determines whether the stack is full or not.'
o peek(): It returns the element at the given position.
o count(): It returns the total number of elements available in a stack.
o change(): It changes the element at the given position.
o display(): It prints all the elements available in the stack.

PUSH operation

The steps involved in the PUSH operation is given below:

o Before inserting an element in a stack, we check whether the stack is full.


o If we try to insert the element in a stack, and the stack is full, then
the overflow condition occurs.
o When we initialize a stack, we set the value of top as -1 to check that the
stack is empty.
o When the new element is pushed in a stack, first, the value of the top gets
incremented, i.e., top=top+1, and the element will be placed at the new
position of the top.
o The elements will be inserted until we reach the max size of the stack.

POP operation

The steps involved in the POP operation is given below:

o Before deleting the element from the stack, we check whether the stack is
empty.
o If we try to delete the element from the empty stack, then
the underflow condition occurs.
o If the stack is not empty, we first access the element which is pointed by
the top
o Once the pop operation is performed, the top is decremented by 1,
i.e., top=top-1.
Applications of Stack

The following are the applications of the stack:

o Balancing of symbols: Stack is used for balancing a symbol. For example,


we have the following program:

int main()
{
cout<<"Hello"; }
cout<<"javaTpoi}

o String reversal: Stack is also used for reversing a string. For example, we want
to reverse a "javaTpoint" string, so we can achieve this with the help of a stack
First, we push all the characters of the string in a stack until we reach the null
character.
o After pushing all the characters, we start taking out the character one by one
until we reach the bottom of the stack.
o UNDO/REDO: It can also be used for performing UNDO/REDO operations.
For example, we have an editor in which we write 'a', then 'b', and then 'c';
therefore, the text written in an editor is abc. So, there are three states, a, ab, and
abc, which are stored in a stack.
o There would be two stacks in which one stack shows UNDO state, and the
other.
o Recursion: The recursion means that the function is calling itself again. To
maintain the previous states, the compiler creates a system stack in which all
the previous records of the function are maintained.
o DFS(Depth First Search): This search is implemented on a Graph, and Graph
uses the stack data structure.
o Backtracking: Suppose we have to create a path to solve a maze problem. If
we are moving in a particular path, and we realize that we come on the wrong
way. In order to come at the beginning of the path to create a new path, we have
to use the stack data structure.
o Expression conversion: Stack can also be used for expression conversion. This
is one of the most important applications of stack. The list of the expression
conversion is given below:
 Infix to prefix
 Infix to postfix
 Prefix to infix
 Prefix to postfix
 Postfix to infix
Memory management:

 The stack manages the memory. The memory is assigned in the


contiguous memory blocks. The memory is known as stack memory as
all the variables are assigned in a function call stack memory.
 The memory size assigned to the program is known to the compiler.
When the function is created, all its variables are assigned in the stack
memory. When the function completed its execution, all the variables
assigned in the stack are released.

Evaluating Arithmetic Expressions

 An expression is any word or group of words or symbols that generates a


value on evaluation. Parsing expression means analyzing the expression for
its words or symbols depending on a particular criterion.
 Expression parsing is a term used in a programming language to evaluate
arithmetic and logical expressions.
 The way to write arithmetic expression is known as a notation. An
arithmetic expression can be written in three different but equivalent
notations, the notations are,
 Infix Notation
 Prefix (Polish) Notation
 Postfix (Reverse-Polish) Notation

Infix Notation
We write expression in infix notation, e.g. a - b + c, where operators are used in-
between operands. It is easy for us humans to read, write, and speak in infix
notation but the same does not go well with computing devices.
Prefix Notation

In this notation, operator is prefixed to operands, i.e. operator is written ahead of


operands. For example, +ab. This is equivalent to its infix notation a + b. Prefix
notation is also known as Polish Notation.

Postfix Notation

This notation style is known as Reversed Polish Notation. In this notation style,
the operator is postfixed to the operands i.e., the operator is written after the
operands. For example, ab+. This is equivalent to its infix notation a + b.

Sr.No. Infix Notation Prefix Notation Postfix Notation

1 a+b +ab ab+

2 (a + b) ∗ c ∗+abc ab+c∗

3 a ∗ (b + c) ∗a+bc abc+∗

4 a/b+c/d +/ab/cd ab/cd/+

5 (a + b) ∗ (c + d) ∗+ab+cd ab+cd+∗

6 ((a + b) ∗ c) – d -∗+abcd ab+c∗d-


Parsing Expressions

Precedence

When an operand is in between two different operators, which operator will take
the operand first, is decided by the precedence of an operator over others. For
example

As multiplication operation has precedence over addition, b * c will be evaluated


first. A table of operator precedence is provided later.

Associativity

Associativity describes the rule where operators with the same precedence appear
in an expression. For example, in expression a + b − c, both + and − have the same
precedence, then which part of the expression will be evaluated first, is determined
by associativity of those operators. Here, both + and − are left associative, so the
expression will be evaluated as (a + b) − c.

Precedence and associativity determines the order of evaluation of an expression.


Following is an operator precedence and associativity table (highest to lowest)

Sr.No. Operator Precedence Associativity

1 Exponentiation ^ Highest Right Associative

2 Multiplication ( ∗ ) & Division ( / ) Second Highest Left Associative


3 Addition ( + ) & Subtraction ( − ) Lowest Left Associative

Postfix Evaluation Algorithm


Step 1. Scan the expression from left to right
Step 2. If it is an operand push it to stack
Step 3. If it is an operator pull operand from stack and perform operation Step 4.
Store the output of step 3, back to stack
Step 5. Scan the expression until all operands are consumed
Step 6. Pop the stack and perform operation

Infix expression:
The expression of the form “a operator b” (a + b) i.e.,
when an operator is in-between every pair of operands.
Postfix expression: The expression of the form “a b operator” (ab+) i.e., When
every pair of operands is followed by an operator.
Examples:
Input: A + B * C + D
Output: ABC*+D+
Input: ((A + B) – C * (D / E)) + F
Output: AB+CDE/*-F+

postfix representation of the expression


The compiler scans the expression either from left to right or from right to left.
Consider the expression: a + b * c + d
 The compiler first scans the expression to evaluate the expression b * c, then
again scans the expression to add a to it.
 The result is then added to d after another scan.

How to convert an Infix expression to a Postfix expression?


To convert infix expression to postfix expression, use the stack data structure.
Scan the infix expression from left to right. Whenever we get an operand, add it
to the postfix expression and if we get an operator or parenthesis add it to the
stack by maintaining their precedence.

 The steps to implement the above idea:


 Scan the infix expression from left to right.
 If the scanned character is an operand, put it in the postfix expression.
 If the scanned character is a ‘(‘, push it to the stack.
 If the scanned character is a ‘)’, pop the stack and output it until a ‘(‘ is
encountered, and discard both the parenthesis.
 Repeat steps 2-5 until the infix expression is scanned.
 Once the scanning is over, Pop the stack and add the operators in the
postfix expression until it is not empty.
 Finally, print the postfix expression.

Postfix expression: 2 3 4 * +

234*+ empty Push 2

34*+ 2 Push 3
4*+ 32 Push 4

Pop 4 and 3, and perform 4*3 =


*+ 432
12. Push 12 into the stack.

Pop 12 and 2 from the stack,


+ 12 2 and perform 12+2 = 14. Push
14 into the stack.

QUEUE ADT
A queue is an ordered collection of data such that the data is inserted at one end
and deleted from another end. The key difference when compared stacks is that in
a queue the information stored is processed first-in first-out or FIFO. In other
words the information receive from a queue comes in the same order that it was
placed on the queue.

Representing a Queue:
One of the most common way to implement a queue is using array. An easy way to
do so is to define an array Queue, and two additional variables front and rear.
The rules for manipulating these variables are simple:
Each time information is added to the queue, increment rear.
Each time information is taken from the queue, increment front.
Whenever front >rear or front=rear=-1 the queue is empty.
Array implementation of a Queue do have drawbacks. The maximum queue size
has to be set at compile time, rather than at run time. Space can be wasted, if we do
not use the full capacity of the array.

Operations on Queue:
A queue have two basic operations:
a)adding new item to the queue
b) removing items fromqueue.
The operation of adding new item on the queue occurs only at one end of the
queue called the rear or back. The operation of removing items of the queue occurs
at the other end called the front.
For insertion and deletion of an element from a queue, the array elements begin at
0 and the maximum elements of the array is maxSize.
The variable front will hold the index of the item that is considered the front of the
queue, while the rear variable will hold the index of the last item in the queue.
Assume that initially the front and rear variables are initialized to -1. Like stacks,
underflow and overflow conditions are to be checked before operations in a queue.
Queue empty or underflow condition is
if((front>rear)
front= =-1) cout
Queue Full or overflow condition is
if((rear==max) cout

Types of Queue

What is a Queue

Queue is the data structure that is similar to the queue in the real world. A queue is
a data structure in which whatever comes first will go out first, and it follows the
FIFO (First-In-First-Out) policy.

Queue can also be defined as the list or collection in which the insertion is done
from one end known as the rear end or the tail of the queue, whereas the deletion
is done from another end known as the front end or the head of the queue.

o Simple Queue or Linear Queue


o Circular Queue
o Priority Queue
o Double Ended Queue (or Deque)

Simple Queue or Linear Queue

Linear Queue, an insertion takes place from one end while the deletion occurs from
another end.
The end at which the insertion takes place is known as the rear end, and the end at
which the deletion takes place is known as front end. It strictly follows the FIFO
rule.

Simple Queue or Linear Queue

Linear Queue, an insertion takes place from one end while the deletion occurs
from another end. The end at which the insertion takes place is known as the rear
end, and the end at which the deletion takes place is known as front end. It strictly
follows the FIFO rule.

Circular Queue

Circular Queue, all the nodes are represented as circular. It is similar to the linear
Queue except that the last element of the queue is connected to the first element. It
is also known as Ring Buffer, as all the ends are connected to another end.

Priority Queue

It is a special type of queue in which the elements are arranged based on the
priority. It is a special type of queue data structure in which every element has a
priority associated with it. Suppose some elements occur with the same priority,
they will be arranged according to the FIFO principle.
Deque (or, Double Ended Queue)

In Deque or Double Ended Queue, insertion and deletion can be done from both
ends of the queue either from the front or rear. It means that we can insert and
delete elements from both front and rear ends of the queue.

Deque can be used both as stack and queue as it allows the insertion and deletion
operations on both ends. Deque can be considered as stack because stack follows
the LIFO (Last In First Out) principle in which insertion and deletion both can be
performed only from one end.

Two Types:

Input restricted deque Input restricted queue, insertion operation can be


performed at only one end, while deletion can be performed from both ends.

Output restricted deque Output restricted queue, deletion operation can be


performed at only one end, while insertion can be performed from both ends.

Application of Queue in Data Structure

Here are some of the common application of queue in data structure:


 Queues can be used to schedule jobs and ensure that they are executed in the
correct order.
 Queues can be used to manage the order in which print jobs are sent to the
printer.
 Queues are used to implement the breadth-first search algorithm.
 Queues can be used to manage incoming calls and ensure that they are
handled in the correct order.
 Queues can be used to manage the order in which processes are executed on
the CPU.
 Queues can be used for buffering data while it is being transferred between
two systems. When data is received, it is added to the back of the queue, and
when data is sent, it is removed from the front of the queue.

Other Application of Queue in Data Structure

Some other application of queue in data structure:

 Applied as buffers on playing music in the mp3 players or CD players.


 Applied on handling the interruption in the operating system.
 Applied to add a song at the end of the playlist.
 Applied as the waiting queue for using the single shared resources like CPU,
Printers, or Disk.
 Applied to the chat application when someone sends messages to us and we
don’t have an internet connection then the messages are stored in the server
of the chat application

Applications of Queues in Real-World Scenarios

Here are the applications of queues in real-world scenarios:

1. Queue in Customer Service Centers

Queues are most commonly observed in customer service systems like banking,
airports, and customer helplines. Customers are served in the order they arrive,
ensuring fairness. This is a straightforward implementation of a simple queue.
2. Print Spooling

When multiple print jobs are submitted to a printer, they are stored in a queue until
processed one by one. The print spooler is an example of a queue application in
real life.

3. Traffic Management Systems

In traffic control and toll booths, vehicles often form a queue as they wait for their
turn. This is an example of queue real-time applications where vehicles are
processed in the order they arrive.

4. Operating System Scheduling

In operating systems, CPU scheduling and task scheduling are based on queues,
where processes are executed in the order they are ready to run. Round-robin
scheduling in operating systems is often implemented using a circular queue.

5. Data Buffers in Networking

In networking, data packets arriving at a router are stored in a queue before being
transmitted to the destination. This helps in managing traffic flow and prevents
packet loss. Network traffic management heavily relies on queues.

Advanced Applications of Queues

Here are the advanced applications of Queues:


1. Load Balancing in Web Servers

Load balancing is a critical application of queue data structure in cloud computing


and web servers. When multiple client requests are made to a server, they are
placed in a queue, and the load balancer distributes them across multiple servers to
prevent overload. This ensures that all requests are handled efficiently.

2. Real-Time Simulation Systems

In simulation systems, queues are used to model and simulate real-world systems
such as manufacturing processes, where resources are allocated based on queue
management. For instance, banking systems simulate customer wait times, while
call centers use queues to manage incoming calls.

3. Memory Management

Memory management systems in operating systems use queues to allocate and


deallocate memory blocks. When a memory block is requested, it is placed in a
queue and is processed in the order it was requested.

4. Event-driven Programming

In event-driven programming, events (such as user actions or system events) are


managed using queues. Event handlers process events in a FIFO manner, ensuring
that the system responds to each event in the order it was triggered.

Linked List ADT


Definition of linked list:

A linked list is a type of linear data structure that occurs when the data elements do
not reside in consecutive memory regions. A linked list's components are
connected using pointers (entities that lead to the next member).
A linked list comprises of nodes, each of which has an information field and a
reference (link) to the subsequent node in that list.

We need linked lists for the various advantages listed below,


 A linked list is a linear data structure that dynamically stores a group of data
segments.
 These data segments are represented by nodes, which are connected by links
or pointers.
 Each node has information stored in a linked list and a reference to the
location of its subsequent node.
Operations in a linked list

Following are the various operations to perform the required action on a linked list:
 Traversal - To access each element of the linked list.

 Insertion - To add/insert a new node to the list.


 Deletion - To remove ane existing node from the list.
 Search - To find a node in the list.
 Sort - To sort the nodes.

Insertion

It’s more than a one-step activity. First, we create a node with the same structure
and specify the location where we’ll insert it.

Suppose, we have to insert Node B between the two nodes A and C.

The new Node B will point to Node C.


Deletion

Just like insertion, deletion is also a multi-step process.

First, we track the node to be removed, by using searching algorithms.

Once, it’s located, we’ll change the reference link of the previous node to the node
that is next to our target node.

In this case, Node A will now point to Node C.

Search an Element on a Linked List

You can search an element on a linked list using a loop using the following steps.
We are finding item on a linked list.
 Make head as the current node.
 Run a loop until the current node is NULL because the last element points
to NULL.
 In each iteration, check if the key of the node is equal to item. If it the key matches
the item, return true otherwise return false.
Example
bool searchNode(struct Node** head_ref, int key) {
struct Node* current = *head_ref;

while (current != NULL) {


if (current->data == key) return true;
current = current->next;
}
return false;
}

Sort Elements of a Linked List

We will use a simple sorting algorithm, Bubble Sort, to sort the elements of a
linked list in ascending order below.
1. Make the head as the current node and create another node index for later use.
2. If head is null, return.
3. Else, run a loop till the last node (i.e. NULL).
4. In each iteration, follow the following step 5-6.

5. Store the next node of current in index.


6. Check if the data of the current node is greater than the next node. If it is greater,
swap current and index.

void sortLinkedList(struct Node** head_ref) {


struct Node *current = *head_ref, *index = NULL;
int temp;
if (head_ref == NULL) {
return;
} else {
while (current != NULL) {
index = current->next;
while (index != NULL) {
if (current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
index = index->next;
}
current = current->next;
}}}

Traverse a Linked List

Displaying the contents of a linked list is very simple. We keep moving the temp
node to the next one and display its contents.

When temp is NULL, we know that we have reached the end of the linked list so
we get out of the while loop.

Example program:

struct node *temp = head;


printf("\n\nList elements are - \n");

while(temp != NULL) {

printf("%d --->",temp->data);

temp = temp->next; }

Types of Linked List

Following are the various types of linked list.

Singly Linked Lists

Singly linked lists contain two "buckets" in one node; one bucket holds the data
and the other bucket holds the address of the next node of the list. Traversals can
be done in one direction only as there is only a single link between two nodes of
the same list.

Doubly Linked Lists

Doubly Linked Lists contain three "buckets" in one node; one bucket holds the
data and the other buckets hold the addresses of the previous and next nodes in the
list. The list is traversed twice as the nodes in the list are connected to each other
from both sides.

Circular Linked Lists

Circular linked lists can exist in both singly linked list and doubly linked list.
Since the last node and the first node of the circular linked list are connected, the
traversal in this linked list will go on forever until it is broken.

What Are The Operations Supported by Linked List?


The operations supported by the linked list data structure are as follows:

 Insertion

This operation is beneficial for adding a new element to the linked list, which can
be done at any position in the list, including the tail or the head.

 Deletion

This operation is beneficial for removing an element from a linked list data
structure. This can also be done at any position on the list.

 Display

With this operation, one can visit each element in the linked list in a specific order
from head to tail.

 Search

This operation allows one to search for a particular element in the linked list data
structure. This can be done by crossing the list and comparing every element to the
target.

Applications of Linked List


The linked list data structure is used to work on various computer science and
programming projects.
 Implementation of Data Structures: Hash tables, stacks in data structures,
and queues are just a few of the significant data structures that may be
implemented using the linked list data structures.
 Memory Management: To efficiently allocate and reallocate memory,
Linked Lists data structures can be utilised in memory management systems.
 File Systems: File systems can be represented using linked lists data
structures. A node represents each file or directory; the links signify the
parent-child relationships between the files and directories.
 Graphs and Charts: Graphs can be represented by Linked Lists data
structure, where each node is a vertex, and the links are the edges that
connect them.
 Making music playlists: Linked List data structures are frequently used to
build music playlists. A node represents each song, and the connections
between the nodes indicate the order in which the songs are played.
 Picture Processing Method: Picture processing methods can be
implemented using linked lists, where a node represents each pixel.

Look here to know more about the Real-time application of data structures.

Uses of Linked List in Data Structure


The main use of a linked list data structure revolves around the storage and
organisation of data flexibly and dynamically. It offers effective insertion and
deletion operations that can be done constantly, either at the tail or head of the list
and also at the linear time in the midst of the list.
Additionally, linked list data structures are essential for implementing other data
structures like queues, hash tables, and stacks, among many more.
Additionally, linked lists also prove beneficial for representing the hierarchical
structure of data, like graphs and trees. If you want to know about Sorting in Data
Structures, look here.

Advantages & Disadvantages of Linked List in Data Structure:


The advantages offered by linked list data structure are as follows:

 Dynamic size: At runtime, linked lists can change their size.


 Effective insertion and deletion: Inserting or removing elements from a list’s
centre may be done quickly and efficiently with linked lists.
 Memory efficiency: linked lists don’t require contiguous memory
allocation.
 Flexibility: Linked lists offer a lot of versatility.

Along with the advantages, some disadvantages linked list data structure offers:

 Sequential access: Linked lists have poor cache locality and significant
memory overhead.
 Absence of random access: As linked lists cannot use random access,
accessing entries directly from an index is impossible.
 Complexity: The implementation and upkeep of linked lists can be more
difficult than those of arrays.

You might also like