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

Stack and Queue

The document discusses stacks, which are a linear data structure that follows the last-in, first-out (LIFO) principle. Stacks have two main operations - push, which adds an item to the top of the stack, and pop, which removes an item from the top. Stacks are commonly used to implement functions calls, undo/redo operations, and backtracking algorithms. Stacks can be implemented using arrays or linked lists, with arrays allowing for constant-time access but requiring more memory overhead.

Uploaded by

Unknown User
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views

Stack and Queue

The document discusses stacks, which are a linear data structure that follows the last-in, first-out (LIFO) principle. Stacks have two main operations - push, which adds an item to the top of the stack, and pop, which removes an item from the top. Stacks are commonly used to implement functions calls, undo/redo operations, and backtracking algorithms. Stacks can be implemented using arrays or linked lists, with arrays allowing for constant-time access but requiring more memory overhead.

Uploaded by

Unknown User
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

Data Structures and

Algorithms

Stack & Queue


What is Data Structure?
A data structure is a way of organising and storing data in a computer so that it can
be accessed and modified efficiently. Some common examples of data structures
include arrays, linked lists, queues, stacks, and trees. Each data structure has its
own advantages and disadvantages, and the choice of which one to use depends on
the specific needs of the task at hand.

Think of a data structure like a recipe for cooking a meal. Just like a recipe with a list
of ingredients and instructions on preparing them, a data structure organises and
stores data in a specific way to make it easy to find, use and change. For example,
an array is like a set of drawers, each one labelled and numbered, where you can
put and take out data in a specific order. A linked list is like a chain of shopping carts,
where each cart contains a small piece of data and a pointer that points to the next
cart, allowing you to move forward and backward through the data. A queue is like a
line at a concert, where new data goes to the back, and the oldest data is removed
from the front. A stack is like a tower of plates, where you can only add or remove
the topmost plate. Finally, a tree is like a family tree, where data is organised in a
hierarchical order with a parent-child relationship. Each data structure has unique
characteristics and can be used for different tasks, just like how different recipes are
used for different dishes.

Classification of Data Structures:


Data structures can be classified into two main categories: linear and non-linear.
Linear data structures are like a one-way street, where data is arranged in sequential
order, one after the other. Examples of linear data structures include arrays, linked
lists, stacks, and queues.
Non-linear data structures are like a maze, where data is not arranged in sequential
order but rather in a more complex and interconnected way. Examples of non-linear
data structures include trees and graphs.

1. Array: A collection of data items that are stored in a contiguous memory


location and can be accessed using an index.
2. Linked List: A collection of data items that are connected together using
pointers, allowing for easy insertion and deletion of elements.
3. Stack: A collection of data items that follow the Last In First Out (LIFO)
principle, where the last element added is the first one to be removed.
4. Queue: A collection of data items that follow the First In First Out (FIFO)
principle, where the first element added is the first one to be removed.
5. Tree: A collection of data items that are organised in a hierarchical structure,
with a parent-child relationship between nodes.
6. Graph: A collection of data items that are organised as a network of
interconnected nodes.
7. Table: A table is a type of data structure that is used to organise and store
data in a tabular format, with rows and columns.
8. Set: A set is a type of data structure that stores a collection of unique items.

What is Stack?
A stack is a 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
stack is referred to as a linear data structure that is sometimes compared to a stack
of plates where only the top plate can be added or removed.
A stack has two primary operations:
1. Push: This operation is used to add an element to the top of the stack.
2. Pop: This operation removes the top element from the stack.
What is meant by Top of the Stack?

The "top of the stack" refers to the element that is most recently added to the stack.
A stack is a Last-In-First-Out (LIFO) data structure, meaning that the last element
added to the stack is the first to be removed. Therefore, the top of the stack is the
element at the end of the stack, also known as the "top" element. The element can
be accessed or removed from the stack next.

LIFO( Last In First Out ):


LIFO stands for Last In First Out. It's a principle that describes the behaviour of a
data structure where the last element added is the first one to be removed.
Imagine a pile of books where you add a new book on top of the pile. The last book
you added will be the first book you take out when you want to read it.
Basic Operations on Stack:
The primary operations that can be performed on a stack are:
1. Push: This operation is used to add an element to the top of the stack. For example,
if you are building a stack of books and want to add a new book on top of the stack,
you will use the push operation.
2. Pop: This operation removes the top element from the stack. For example, you are
reading a book, and you finish it. You will use the pop operation to remove it from the
top of the stack.
3. Peek: This operation is used to return the top element of the stack without removing
it. For example, if you want to know the next book you will read, you will use the peek
operation to see the top element of the stack without removing it.
4. IsEmpty: This operation is used to check whether the stack is empty. For example, if
you want to know if there are more books to read, you will use the IsEmpty operation
to check if the stack is empty.
5. Size: This operation checks the number of elements in the stack. For example, if you
want to know how many books you have in the stack, you will use the Size operation
to check the number of elements in the stack.

Push:
Adds an item to the stack. If the stack is full, then it is said to be an Overflow
condition.

Algorithm for push:


Pop:
Removes an item from the stack. The items are popped in the reversed order in
which they are pushed. If the stack is empty, then it is said to be an Underflow
condition.

Algorithm for pop:

Top:
Returns the top element of the stack.

Algorithm for Top:


isEmpty:
Returns true if the stack is empty, else false.

Algorithm for isEmpty:

Understanding stack practically:


Understanding stacks practically can be done by considering an example of a web
browser, where the back button is used to go back to the previous page. The
browser keeps track of the pages visited by the user in a stack, with the current page
at the top of the stack.
● When the user visits a new page, the browser adds the page to the top of the
stack using the push operation.
● When a user has clicked the back button, the browser uses the pop operation
to remove the currently displayed page from the top of the stack and display
the page that was put before it.
● When the user clicks the forward button, the browser uses the peek operation
to check the top of the stack, if there is no page, it means the stack is empty, if
there is a page, it reveals the page without removing it.
● The forward button will be disabled if the stack is empty because there are no
more pages to forward to, which the browser can check using the IsEmpty
operation.
● The browser also uses the Size operation to check the number of elements in
the stack, to know how many pages the user visited.

Complexity Analysis:
Time Complexity
Types of Stacks:
Register Stack: A specific kind of stack that is kept in the CPU's registers is known
as a register stack. Due to their location within the CPU and ease of access, these
kinds of stacks operate incredibly quickly. They are commonly used for the
short-term storing of data or for keeping track of the locations of function calls.

Memory Stack:A memory stack, on the other hand, is a type of stack that is stored
in the computer's main memory. These types of stacks are slower than register
stacks because they are located outside of the CPU, but they can store more data
than register stacks. They are often used for more permanent storage of data, such
as program execution context.

Applications of the stack:


Stacks have a wide range of applications in computer science and programming.
Some examples include:
1. Memory management: Stacks are used to keep track of memory allocation
and deallocation.
2. Function calls: Stacks keep track of function calls and return addresses in a
program's execution.
3. Expression evaluation: Stacks evaluate mathematical expressions, such as
infix and postfix expressions.
4. Recursion: Stacks are used to implement recursion, a technique in which a
function calls itself to solve a problem.
5. Compiler design: Stacks are used in the compilation process to keep track of
symbols, parse expressions, and generate code.
6. Undo and Redo operations: Stacks can be used in maintaining the history of
operations for undo and redo functionality.
7. Backtracking: Stacks are used to backtracking through a series of steps, such
as in pathfinding algorithms.
8. Web browsers: The back and forward features in web browsers are
implemented via stacks.
9. Parsing: A stack can be used to parse sentences in natural language
processing.
Implementation of Stack:
There are two ways to implement a stack

● Using array
● Using linked list

Implementing Stack using Arrays:

This implementation uses a Python list as the underlying array for the stack. The
push() method adds an item to the stack by appending it to the list. The pop()
method removes and returns the last item from the list. The peek() method returns
the last item from the list without removing it. The is_empty() method returns True if
the list is empty, and False otherwise. The get_stack() method returns the current
stack.
Advantages of array implementation:

● Constant time access for elements


● Easy to implement
● Dynamic resizing
● Cache-friendly
● No need for a separate pointer
● Memory efficient
● Simple and straightforward to understand
● Support for multiple types of data

Disadvantages of array implementation:

● Fixed-size, once full, cannot hold more items without resizing


● Wasteful when the stack is not full
● Resizing can be expensive and cause memory fragmentation
● Extra space is needed for resizing
● Not cache-friendly when resizing
● No support for dynamic memory allocation
● No support for large data types

Implementing Stack using Linked List:


This implementation uses a linked list where each node has a data value and a
reference to the next node. The push() method adds a new node to the top of the
stack. The pop() method removes and returns the top node's data. The peek()
method returns the top node's data without removing it. The is_empty() method
returns True if the stack is empty, and False otherwise. The get_stack() method
prints the current stack.
Advantages of Linked List implementation:

● Dynamic size: Linked list-based stack can adjust its size according to the
number of elements, and it can grow or shrink as needed.
● No wasted space: Linked list-based stack does not waste space when it's not
full and does not need to be resized.
● No memory fragmentation: Linked list-based stack does not cause memory
fragmentation as it only uses the memory it needs.
● Dynamic memory allocation: Linked list-based stack supports dynamic
memory allocation. It can handle large amounts of data.
● Support for large data types: Linked list-based stack can handle large data
types such as images or videos.
● Cache-friendly: Linked list-based stack is cache-friendly as it only needs to
access the current node and the next node; this reduces cache misses.
● Simple to understand: The linked list-based implementation is simple and
easy to understand as it represents the stack.
● Support for multiple data types: A linked list-based stack can store various
data types, for example, integers, strings, or objects.

Disadvantages of Linked List implementation:

● Slower than array-based implementation: Accessing elements in a linked list


is slower than an array because it requires traversing the list to find the
desired element. It has O(n) time complexity in the worst case.
● More memory overhead: Each node in a linked list requires extra memory for
the next pointer, which increases the memory overhead.
● Not cache-friendly when traversing: When traversing the linked list, the data is
not stored in contiguous memory locations, and this can cause cache misses
and reduce performance.
● Not suitable for specific use cases: Linked list-based stack may not be ideal
for particular use cases, such as low-level programming or real-time systems
where performance is critical.
● Risk of memory leaks: Linked list-based stack could cause memory leaks if
not implemented correctly, as it uses dynamic memory allocation.

Application of Stack Data Structure:

Stacks are used in a variety of applications, such as:


● Memory management
● Function calls and return addresses
● Expression evaluation
● Recursion
● Compiler design
● Undo and Redo operations
● Backtracking
● Web browsers for Back and Forward functionality
● Parsing in natural language processing
● Algorithms and data structures include Depth-first Search, Topological Sort,
and Tower of Hanoi.

Advantages of Stack:

● Constant time access for elements in case of array implementation.


● Dynamic size in case of linked list implementation.
● Used in various applications such as memory management, function calls,
expression evaluation, recursion, and many more.
● Simple and easy-to-understand data structure.
● Can handle large data types such as images or videos in case of linked list
implementation.
● Cache-friendly in case of array-based implementation.
● Support for multiple types of data

Disadvantages of Stack:

● Fixed-size in case of array-based implementation.


● Wasteful when the stack is not full in the case of array-based implementation.
● Resizing can be expensive and cause memory fragmentation in the case of
array-based implementation.
● Slower than array-based implementation in the case of linked list
implementation.
● More memory overhead in the case of linked list implementation.
● Not cache-friendly when traversing in case of linked list implementation.
● Not suitable for specific use cases where performance is critical.
● If not implemented correctly, there is a risk of memory leaks in the case of
linked list implementation.

What is Queue Data Structure?


A queue is a linear data structure that follows the First-In-First-Out (FIFO) principle.
This means that the first element added to the queue will be the first one to be
removed. A queue is similar to a real-world queue, like a line of people waiting to buy
tickets; the first person in the line will be the first one to get the tickets.
In a queue, two primary operations can be performed:
1. Enqueue: This operation adds an element to the back of the queue.
2. Dequeue: This operation removes an element from the front of the queue.

FIFO Principle of Queue:


In the context of a queue data structure, according to the FIFO principle, the first
item added to the queue will also be the first one taken out.

This means that when an element is added to the queue, it is placed at the rear of
the queue, and when an element is removed from the queue, it is removed from the
front of the queue.

The element that has been in the queue the longest is the one that is removed first.
This principle ensures that elements are removed in the order they were added,
making it a first-in, first-out data structure
Imagine a line at a store as a real-world example; the person who is first in line will
get service. That is how the queue works, the first element added to the queue is the
first one to be removed. Like a queue at a store, the first person who joins the queue
will be the first one to leave the queue.
Characteristics of Queue:

● A linear data structure that follows the First-In-First-Out (FIFO) principle.


● Two primary operations can be performed: Enqueue (add an element to the
back of the queue) and Dequeue (remove an element from the front of the
queue).
● It can be implemented using an array or a linked list.
● Has a front and a rear; the front points to the first element of the queue, and
the rear points to the last element.
● They are used in various applications such as task scheduling, handling
interrupts in operating systems, managing multiple requests for printers and
disk access, and many more.

Types of Queue:

There are several types of queues, including:

1. Simple Queue: A simple queue is a basic implementation of a queue data


structure, where elements are added to the rear and removed from the front.

2. Circular Queue: A circular queue is a variation of the simple queue, where the
rear pointer wraps around to the front when it reaches the end of the array,
allowing for efficient memory use.

3. Priority Queue: A priority queue is where each element has an associated


priority, and elements are dequeued in order of their preference.

4. Double-Ended Queue (Deque): A Double-Ended Queue (Deque) is a queue


that allows insertions and deletions at both ends.
Basic Operations for Queue in Data Structure:
A queue data structure can be used to execute the following basic operations:
1. Enqueue: This operation adds an element to the rear of the queue.
2. Dequeue: This operation removes an element from the front of the queue.
3. Peek or Front: This operation returns the element at the front of the queue
without removing it.
4. Is Empty: This operation checks if the queue is empty or not.
5. Size: This operation returns the number of elements in the queue.
6. Display: This operation displays all the elements in the queue.
7. Clear: This operation removes all the elements from the queue.

Enqueue():
Enqueue is a basic operation in queue data structure, it is used to add an element to
the rear of the queue.

The algorithm for enqueue operation is as follows:


1. Check if the queue is full. If it is, return an error message or raise an
exception.
2. Create a new node with the data to be enqueued.
3. If the queue is empty, set the front and rear pointers to the new node.
4. If the queue is not empty, set the next pointer of the rear node to the new
node, and update the rear pointer to the new node.
5. Increase the size of the queue.
Dequeue():
Dequeue is a basic operation in queue data structure, it is used to remove an
element from the front of the queue. It is the opposite of the enqueue operation.
When an element is dequeued, it is removed from the front of the queue, and all the
elements behind it move up one position.

The algorithm for the dequeue operation is as follows:


1. Check if the queue is empty. If it is, return an error message or raise an
exception.
2. Store the data of the front node in a temporary variable.
3. Move the front pointer to the next node in the queue.
4. If the front pointer becomes None, set the rear pointer to None as well.
5. Decrease the size of the queue.
6. Return the stored data.

Front():
The front() operation is used to access the element at the front of the queue without
removing it.
The algorithm for the front operation is as follows:
1. Check if the queue is empty. If it is, return an error message or raise an
exception.
2. Return the data of the front node.
Queue Representation:

A queue can be represented in several ways, but the most common representations
are:
1. Array-based representation: A queue is represented by an array. The array's
first and last elements are the front and back of the queue, respectively.
Enqueue and dequeue operations are performed by moving the front and rear
pointers, respectively.
2. Linked List representation: A linked list is used to represent a queue. The front
of the queue is the head of the list, and the rear is the tail of the list. Enqueue
and dequeue operations are performed by adding and removing elements

Array representation of queue:


In this example, the queue is implemented as an array with a fixed capacity. The
enqueue() method adds an element to the rear of the queue, and the dequeue()
method removes an element from the front of the queue. The is_full() and is_empty()
methods check if the queue is full or empty, respectively.
Linked List Representation of Queue:
In this example, the queue is implemented as a linked list. The enqueue() method
adds a new node to the rear of the queue and the dequeue() method removes a
node from the front of the queue. The is_empty() method checks if the queue is
empty.

Applications of Queue:
Queues have several applications in various fields; here are a few examples of how
queues are used in real-world scenarios:
1. Operating Systems: Queues are used to manage processes and tasks.
2. Networking: Queues are used in networking to manage incoming and
outgoing data packets.
3. Simulation: Queues simulate real-world systems such as bank teller lines,
printing queues, and more.
4. Web servers: Queues are used to handle incoming requests in web servers
and manage the server load.
5. BFS(Breadth First Search) Algorithm: Queue is used as a fundamental data
structure to implement the BFS algorithm.
6. Graphics processing: Queues are used to manage the rendering order of 3D
graphics.
7. Real-time systems: Queues are used to manage real-time events and to
ensure that events are processed in the order they occur.
8. Priority Queue: Queues can be used to implement priority queues. In this kind
of queue, the element with the highest priority is processed first.

Advantages of Queue:

1. First-In-First-Out (FIFO) ordering, which is the method queues use, makes


sure that the first element added to the queue is also the first one deleted.
2. Queues can be used to implement efficient algorithms for breadth-first search
and other similar tasks.
3. Queues are useful for handling asynchronous tasks and coordinating
communication between different system parts.
4. Queues can be used to implement load balancing, which distributes tasks
evenly among multiple processors.
5. Queues can be used to implement priority queues, where elements are
dequeued in order of priority.
6. A linked list or an array can be used to implement queues, which are simple
and efficient data structures.
7. Queues can be used to buffer data in communication systems so that data
can be sent and received at a steady rate.

Disadvantages of Queue:

1. Queues have a fixed size, so they can become full and not be able to insert
elements.
2. Queues are not suitable for cases where random access is required.
3. A queue can cause memory waste if the queue is too big and the elements
are dequeued too quickly.
4. If a priority queue is not implemented carefully, it can lead to starvation, where
lower priority elements are never served.
5. Queues can be a source of latency when the dequeue is slow, and the
enqueue is fast.
6. Queues can be a source of contention when multiple processes try to access
the same queue simultaneously.
7. Queues are not suitable for cases where elements' order is unimportant or
elements need to be accessed in random order.
If you're looking to get into Web Development,
then AlmaBetter is the best place to start your
journey.

Join our Full Stack Web Development Program


and launch your career in tech today!

Link: https://link.almabetter.com/9w63

You might also like