Formatted DSA Report
Formatted DSA Report
2024 – 2025
in
CSE (AI&ML)
Submitted By
RASHMI B C
RN SHETTY TRUST®
(NAAC ‘A+ Grade’ Accredited, NBA Accredited (UG - CSE, ECE, ISE, EIE and EEE)
Channasandra, Dr. Vishnuvardhan Road, Bengaluru - 560 098
CERTIFICATE
Certified that the Case study entitled “Node by Node: Unlocking Power of Linked
Lists” carried out by Krishna P Kulkarni [1RN23CI081] , Manish S [1RN23CI089]
and Hariprasad Vittannavar [1RN23CI068] are Bonafide students of RNS Institute of
Technology in partial fulfilment for the award of “BACHELOR OF ENGINEERING” in
CSE (AI&ML) as prescribed by VISVESVARAYA TECHNOLOGICAL UNIVERSITY,
BELAGAVI during the academic year 2024 – 25. It is certified that all
corrections/suggestions indicated for internal assessment have been incorporated
in the report deposited in the departmental library. The Case study has been
approved as it satisfies the academic requirements in respect of Case study on Data
Structure and its Applications (BCS304) prescribed for the said degree.
RNSIT
Abstract
Linked lists are a foundational data structure in computer science, valued for their
dynamic memory management and adaptability in various computational tasks.
Unlike arrays, linked lists utilize a node-based architecture where each element, or
node, consists of data and a pointer to the next node. This structure enables efficient
insertion and deletion operations but poses unique challenges in implementation
and understanding, especially for beginners.
This case study, "Node by Node: Unlocking the Power of Linked Lists," explores the
architecture, functionality, and applications of linked lists, aiming to demystify their
role in modern computing. The study begins with a detailed explanation of the core
components of linked lists. A single node acts as the building block, storing data and
a pointer that links it to the next node. These nodes collectively form linear or
circular sequences, depending on the design. This structure is dissected to highlight
its advantages over static data structures like arrays, particularly in scenarios
requiring dynamic resizing or memory-efficient operations.
This distinction makes them invaluable in real-time systems and applications where
adaptability is crucial. In conclusion, "Node by Node: Unlocking the Power of Linked
Lists" highlights the versatility, efficiency, and significance of linked lists in
computer science. By unravelling their complexities and showcasing their practical
applications, this study equips learners and practitioners with the tools to
confidently implement and optimize linked lists in diverse computational contexts.
iii
CHAPTER 1
INTRODUCTION
A linked list is a linear data structure which can store a collection of "nodes"
connected together via links i.e. pointers. Linked lists nodes are not stored at a
contiguous location, rather they are linked using pointers to the different memory
locations. A node consists of the data value and a pointer to the address of the next
node within the linked list.
A linked list is a dynamic linear data structure whose memory size can be allocated
or de-allocated at run time based on the operation insertion or deletion, this helps in
using system memory efficiently. Linked lists can be used to implement various data
structures like a stack, queue, graph, hash maps.
A linked list starts with a head node which points to the first node. Every node
consists of data which holds the actual data (value) associated with the node and a
next pointer which holds the memory address of the next node in the linked list. The
last node is called the tail node in the list which points to null indicating the end of
the list.
A linked list is a linear data structure in which elements, called nodes, are stored in a
sequence where each node points to the next one. Unlike arrays, where elements are
stored in contiguous memory locations, linked lists store elements in non-
contiguous memory, with each node consisting of two parts: data and a pointer (or
reference) to the next node. This allows dynamic memory allocation, making linked
lists more flexible in terms of size, as they can grow or shrink during runtime
without the need for reallocation or resizing.
Linked lists are often used when the number of elements is unknown ahead of time
or changes frequently. They can be classified into different types, such as singly
linked lists, doubly linked lists, and circular linked lists. In a singly linked list, each
node points to the next node, while in a doubly linked list, each node contains
references to both the next and the previous node, allowing traversal in both
directions.
Circular linked lists are a variation where the last node points back to the first node,
forming a circle. Linked lists have numerous advantages, such as efficient insertion
and deletion of elements, especially in cases where elements are frequently added
or removed from the list.
CHAPTER 2
PROJECT DESIGN
In case of arrays, the size is given at the time of creation and so arrays are of fixed
length whereas Linked lists are dynamic in size and any number of nodes can be
added in the linked lists dynamically.
Advantages of Linked List over arrays :
Efficient insertion and deletion. : We only need to change few pointers (or
references) to insert (or delete) an item in the middle. at any point in a linked list
take O(1) time. Whereas in an data structure, insertion / deletion in the middle
takes O(n) time.
Space Efficient in Some Cases : Linked List might turn out to be more space efficient
compare to arrays in cases where we cannot guess the number of elements in
advance. In case of arrays, the whole memory for items is allocated together. Even
with dynamic sized arrays like vector in C++ or list in Python or Array/List in Java.
the internal working involves de- allocation of whole memory and allocation of a
bigger chunk when insertions happen beyond the current capacity.
Circular List with Deletion/Addition : Circular Linked Lists are useful to implement
CPU round robin scheduling or similar requirements in the real world because of
the quick deletion/insertion in a circular manner.
Random Access. : We can access ith item in O(1) time (only some basic arithmetic
required using base address). In case of linked lists, it is O(n) operation due to
sequential access.
Cache Friendliness : Array items (Or item references) are stored at contiguous
locations which makes array cache friendly (Please refer for more details)
Easy to use : Arrays are relatively very easy to use and are available as core of
programming languages
Less Overhead : Unlike linked list, we do not have any extra references / pointers to
be stored with every item.
A singly linked list is a linear data structure in which each element, known as
a node, contains two components: the data and a reference (or pointer) to the next
node in the sequence. The list starts with a head node and ends with a node whose
pointer is set to null, indicating the termination of the list. Unlike arrays, which are
contiguous in memory, linked lists are non-contiguous, meaning nodes can be
stored in different locations in memory, with each node pointing to the next one.
One of the key advantages of a singly linked list is its dynamic memory allocation.
This means the size of the list can grow or shrink during runtime, which is more
efficient than arrays that require resizing. Insertion and deletion operations,
especially at the beginning or middle of the list, are efficient, as only the pointers
need to be adjusted. However, accessing an element requires sequential traversal
from the head node, which makes random access less efficient. Singly linked lists are
widely used in applications such as dynamic memory allocation, implementing
queues and stacks, and managing data that changes frequently. Despite their
simplicity, singly linked lists offer flexibility and efficiency for specific data
management tasks.
A doubly linked list is a dynamic data structure that consists of nodes linked in both
forward and backward directions. Each node in a doubly linked list contains three
components: data, a pointer to the next node (forward link), and a pointer to the
previous node (backward link). This bidirectional linking makes doubly linked lists
more flexible compared to singly linked lists, where nodes only have a single pointer
to the next node. The key advantage of a doubly linked list is its ability to traverse in
both directions, which makes certain operations, such as reverse traversal and
deletion,
more efficient. For instance, to delete a node in a singly linked list, one must first
locate the node's predecessor, which can be cumbersome. In a doubly linked list, the
backward pointer eliminates this need, allowing direct access to the preceding node.
Doubly linked lists are widely used in scenarios requiring dynamic memory
allocation and frequent insertion or deletion operations, such as navigation systems,
undo/redo functionality in applications, and managing playlists. Despite their
benefits, doubly linked lists have higher memory overhead due to the additional
pointer in each node and slightly more complex algorithms for node manipulation.
However, their versatility makes them a valuable data structure in computer science
.
A circular linked list is a dynamic data structure where the last node is linked back
to the first node, forming a continuous loop. Unlike a linear linked list, where the
end is marked by a null pointer, a circular linked list has no beginning or end. Each
node contains data and a pointer to the next node, and in a doubly circular linked
list, nodes also have a pointer to the previous node. Circular linked lists offer unique
advantages in specific applications. Their looping nature is beneficial in scenarios
requiring repetitive traversal, such as buffering, round-robin scheduling, or real-
time systems. For example, in a music player, a circular linked list can efficiently
handle playlists that repeat seamlessly. Traversing a circular linked list can begin at
any node and continue indefinitely until a specific stopping condition is met.
However, care must be taken to avoid infinite loops during traversal. The dynamic
memory allocation of circular linked lists allows efficient insertion and deletion at
any point without reorganization. While their circular structure simplifies some
operations, they introduce complexity in managing node traversal and termination
conditions.
Despite these challenges, circular linked lists are a powerful tool for applications
requiring cyclical processing or dynamic, continuous data flow.
CHAPTER 3
IMPLEMENTATION
The basic operations in the linked lists are insertion, deletion, searching, display,
and deleting an element at a given key. These operations are performed on Singly
Linked Lists as given below −
Adding a new node in linked list is a more than one step activity. We shall learn this
with diagrams here. First, create a node using the same structure and find the
location where it has to be inserted.
This will put the new node in the middle of the two. The new list should look like
this −
Insertion at Beginning
Insertion at Ending
In this operation, we are adding an element at the ending of the list.
In this operation, we are adding an element at any position within the list.
Deletion is also a more than one step process. We shall learn with pictorial
representation. First, locate the target node to be removed, by using searching
algorithms.
We need to use the deleted node. We can keep that in memory otherwise we can
simply deallocate memory and wipe off the target node completely.
Deletion at Beginning
In this deletion operation of the linked, we are deleting an element from the
beginning of the list. For this, we point the head to the second node.
Deletion at Ending
In this deletion operation of the linked, we are deleting an element from the ending
of the list.
In this deletion operation of the linked, we are deleting an element at any position of
the list.
The traversal operation walks through all the elements of the list in an order and
displays the elements in that order.
Link − Each link of a linked list can store a data called an element.
Next − Each link of a linked list contains a link to the next link called Next.
Prev − Each link of a linked list contains a link to the previous link called Prev.
Linked List − A Linked List contains the connection link to the first link called First
and to the last link called Last.
In a data structure, a doubly linked list is represented using nodes that have three
fields:
Data
Doubly Linked List contains a link element called first and last.
Each link carries a data field(s) and a link field called next.
Each link is linked with its next link using its next link.
Each link is linked with its previous link using its previous link.
The last link carries a link as null to mark the end of the list.
Backward Traversal:
Efficient traversal in both directions: Doubly linked lists allow for efficient traversal
of the list in both directions, making it suitable for applications where frequent
insertions and deletions are required.
Easy insertion and deletion of nodes: The presence of pointers to both the previous
and next nodes makes it easy to insert or delete nodes from the list, without having
to traverse the entire list.
Can be used to implement a stack or queue: Doubly linked lists can be used to
implement both stacks and queues, which are common data structures used in
programming.
More complex than singly linked lists: Doubly linked lists are more complex than
singly linked lists, as they require additional pointers for each node.
More memory overhead: Doubly linked lists require more memory overhead than
singly linked lists, as each node stores two pointers instead of one.
Cache implementation where quick insertion and deletion of elements are required.
Browser history management to navigate back and forth between visited pages.
In this operation, we create a new node with three compartments, one containing
the data, the others containing the address of its previous and next nodes in the list.
This new node is inserted at the beginning of the list.
Doubly Linked List - Insertion at the End
In this insertion operation, the new input node is added at the end of the doubly
linked list; if the list is not empty. The head will be pointed to the new node, if the
list is empty.
This deletion operation deletes the existing first nodes in the doubly linked list. The
head is shifted to the next node and the link is removed.
Circular Linked List is a variation of Linked list in which the first element points to
the last element and the last element points to the first element. Both Singly Linked
List and Doubly Linked List can be made into a circular linked list.
In singly linked list, the next pointer of the last node points to the first node.
In doubly linked list, the next pointer of the last node points to the first node and the
previous pointer of the first node points to the last node making the circular in both
directions.
The last link's next points to the first link of the list in both cases of singly as well as
doubly linked list.
The first link's previous points to the last of the list in case of doubly linked list.
However, due to the fact that we are considering circular linked list in the memory
therefore the last node of the list contains the address of the first node of the list.
We can also have more than one number of linked list in the memory with the
different start pointers pointing to the different start nodes in the list. The last node
is identified by its next part which contains the address of the start node of the list.
We must be able to identify the last node of any linked list so that we can find out
the number of iterations which need to be performed while traversing the list.
The insertion operation of a circular linked list only inserts the element at the start
of the list. This differs from the usual singly and doubly linked lists as there is no
particular starting and ending points in this list. The insertion is done either at the
start or after a particular node (or a given position) in the list.
The Deletion operation in a Circular linked list removes a certain node from the list.
The deletion operation in this type of lists can be done at the beginning, or a given
position, or at the ending.
CHAPTER 4
Linked lists provide a flexible way to implement stacks (Last In First Out) and
queues (First In First Out). Unlike arrays, no resizing is needed, and insertion or
deletion at the head or tail is efficient, making them suitable for applications like
function calls or task scheduling. Stacks and queues are commonly implemented
using linked lists, enabling efficient insertion and deletion without resizing.
Operating systems use linked lists to maintain file allocation tables, enabling
efficient file storage and retrieval by linking file blocks. Many operating systems
employ linked lists to manage files and directories. For instance, the File Allocation
Table (FAT) uses linked lists to track file blocks on disk, enabling efficient storage,
retrieval, and management of fragmented data
Undo/Redo in Applications
Applications like text editors use linked lists to implement undo and redo
functionality, maintaining a sequential list of changes.The undo/redo functionality
in applications like text editors or design tools can be efficiently implemented using
a doubly linked list. Each node represents a state of the document or project, with
pointers to the previous and next states.
When a user performs an action, a new node is created. Undoing moves to the
previous node, and redoing moves to the next. This structure allows seamless
navigation through action history, enabling efficient and dynamic state
management.
Polynomial Representation
Linked lists efficiently represent and manage sparse polynomials by linking non-
zero terms without needing a large array. Linked lists represent polynomials by
storing coefficients and exponents in nodes. Linked lists represent polynomials by
storing terms as nodes, with coefficients and exponents. This enables efficient
manipulation, such as addition or multiplication, without needing predefined sizes
or reorganization.
Dynamic Graphs
Adjacency lists in graph algorithms are often implemented using linked lists for
efficient representation of dynamic edges .It can be effectively represented using
linked lists, particularly in the form of an adjacency list. Each vertex in the graph is
associated with a linked list storing its adjacent vertices. This representation is
efficient for dynamic graphs where edges or vertices are frequently added or
removed. Linked lists allow these updates without requiring restructuring, unlike
matrices. This makes them ideal for applications like social networks, routing
algorithms, and real-time network modeling.
Linked lists handle sparse data efficiently by linking non-empty data elements,
reducing memory overhead compared to arrays. Linked lists provide memory-
efficient handling by dynamically allocating memory for each element as needed,
unlike arrays that require pre- defined fixed sizes. Each node in a linked list contains
data and a pointer, which allows efficient memory usage by allocating only the
necessary space for elements. This is particularly useful in applications where the
data size fluctuates, such as dynamic memory management, real-time systems, or
large-scale databases, as linked lists avoid memory wastage associated with static
structures.
Web Browsers
Browsers use linked lists for maintaining history stacks, enabling back-and-forth
navigation seamlessly. Web browsers use linked lists to manage navigation history,
enabling efficient
movement through previously visited pages. A doubly linked list stores URLs,
allowing users to go forward and backward in their browsing history. Each node
contains a URL and pointers to the next and previous pages. This structure supports
features like the back and forward buttons, history tracking, and session
management, ensuring smooth and efficient navigation through a dynamic,
constantly changing browsing environment.
Music Players
Playlists in music applications use linked lists to link songs, allowing dynamic
additions, deletions, and shuffling. In a music player, linked lists are used to manage
playlists and tracks efficiently. A doubly linked list allows users to navigate through
songs in both forward and backward directions, enabling features like shuffle,
repeat, and seamless transitions between tracks. Each node in the list contains
metadata such as the song title, artist, and a pointer to the next and previous songs.
This structure enables dynamic playlist management, easy insertion or deletion of
tracks, and efficient song navigation.
Real-Time Simulations
Complexity in Traversal:
Unlike arrays, where elements are accessed using an index, linked lists require
sequential traversal from the head node, as each node is only aware of its
neighboring nodes. This makes accessing elements at arbitrary positions more time-
consuming, especially for larger lists, since you cannot directly access a specific
element without traversing from the beginning.
In a singly linked list, reverse traversal is not possible since each node only stores a
reference to the next node, not the previous one. For reverse traversal, you would
need to traverse the entire list first to collect the data or implement extra logic to
reverse the list, which increases complexity and execution time.
Linked lists do not support constant-time random access to elements, unlike arrays,
where elements can be accessed directly using an index. To access an element in a
linked list, you must start from the head and traverse the list node by node. This
results in linear time complexity (O(n)) for accessing an element at a given position,
which is inefficient compared to arrays' O(1) access.
Pointer Management:
Deletion Complexity:
While deleting a node from a linked list can be straightforward, it becomes complex
when dealing with a singly linked list. In order to delete a node, you must ensure
that the previous node correctly points to the next node. If you're deleting from the
middle or end, and don’t have a reference to the previous node, you have to traverse
the list to locate it, which introduces additional steps and increases time complexity.
Fragmentation:
Since linked lists allocate memory dynamically for each node, they can cause
memory fragmentation over time. As nodes are added and removed, memory can
become fragmented, leading to inefficient use of available space. In contrast to
contiguous data structures like arrays, which require a single large block of
memory, linked lists may lead to scattered memory allocation, which can affect
performance and make it harder to manage memory effectively.
Dynamic Size:
Linked lists do not require predefined sizes, unlike arrays that must be allocated
with a fixed size. This dynamic nature allows the list to grow or shrink as needed,
making it more efficient in memory usage when the size of the data is unpredictable.
You don’t need to worry about over-allocating or running out of space as in arrays.
Linked lists provide efficient insertion and deletion operations, especially at the
beginning or middle of the list. Inserting or deleting a node only requires updating a
few pointers, and does not involve shifting elements, as is the case with arrays. This
makes linked lists well-suited for applications where data changes frequently, such
as managing active processes in operating systems.
No Wasted Memory:
Since memory is allocated dynamically for each node as needed, linked lists avoid
the problem of memory wastage that occurs in arrays. In arrays, if the allocated size
is too large, unused
memory goes to waste, while if it's too small, it can lead to overflow. Linked lists
allocate memory only when necessary, making them more memory-efficient in
dynamic environments.
Linked lists can easily expand or contract without the need to reallocate or copy
data, unlike arrays, which may require resizing or reallocating when elements are
added or removed. In linked lists, each new node can be inserted without worrying
about the capacity of the list, as each node simply points to the next, and the list
adapts dynamically.
Linked lists don’t require contiguous memory blocks. Each node can be stored at
any location in memory, and the nodes are connected through pointers. This makes
linked lists particularly useful in systems with fragmented memory or when
allocating memory dynamically for a growing data structure, as the data doesn't
have to be contiguous like in arrays.
Linked lists are ideal for implementing queue and stack data structures because of
their dynamic nature. In a stack or queue, elements are added or removed from the
ends (push/pop or enqueue/dequeue), which can be performed in constant time
(O(1)) by simply updating pointers. This avoids the need to shift elements as in
array-based implementations, improving performance.
Linked lists manage memory more efficiently in dynamic environments. Since each
node is created when needed, and there’s no need to pre-allocate a large block of
memory, it’s easier to manage memory usage. This is particularly helpful for
applications in systems where
Real-Life Examples
In music players, linked lists are used to manage playlists. Each song in the playlist
is
represented as a node, and each node contains information about the song and a
pointer to the next one. This allows users to efficiently add, remove, or reorder
songs. A doubly linked list is particularly useful, as it enables both forward and
backward navigation, allowing users to move through the playlist in either direction
(e.g., forward to the next song or backward to the previous one).
Browser History:
Web browsers use linked lists to manage the browsing history. Each webpage
visited is stored as a node, with pointers to the next and previous pages. This
enables efficient navigation through the history using the "Back" and "Forward"
buttons. The doubly linked list allows users to go backward to previously visited
pages and forward to the ones they were previously on, providing a seamless
browsing experience.
Operating System Process Scheduling:
Linked lists are used by operating systems to manage processes in queues. For
example, the ready queue or waiting queue for processes is often implemented as a
linked list. Each process is represented as a node, and the system can efficiently add
or remove processes from these queues. The dynamic nature of linked lists allows
the operating system to adjust to changing workloads by adding or removing
processes as needed without requiring reallocation of memory.
In train stations, linked lists can be used to manage trains on different platforms.
Each train, with its schedule and platform number, is represented as a node in the
list. The system can dynamically adjust, adding new trains to the platform, removing
trains that have departed, or changing their platform assignments. The flexibility of
linked lists allows for efficient management of trains in real-time without requiring
large, fixed-size memory allocations.
Text Editors:
In text editors like Microsoft Word or code editors, linked lists are used to manage
text files. Each line of text is often stored as a node, and the list allows the editor to
efficiently add, remove, or modify text. This approach is particularly useful for large
files, as it avoids the need to shift all the characters in memory when a single change
is
made, unlike in arrays. Linked lists help in handling frequent insertions and
deletions of text while maintaining a smooth editing experience.
Navigation Systems:
In GPS navigation or routing systems, linked lists can represent routes or paths.
Each node stores information about a location or waypoint, with a pointer to the
next stop. This allows the system to dynamically add new routes or modify existing
ones without needing to reprocess the entire path. If a new detour or stop is added,
the list is updated accordingly, and the system can provide optimal routes based on
real-time conditions.
Social Networks:
Linked lists can be used in social networking sites to represent user connections or
friend lists. Each user is a node in the list, and the list allows for efficient addition
and removal of friends, making it easy to update connections. A doubly linked list
can be particularly useful for representing bi-directional relationships (e.g., friends
who follow each other), allowing users to easily navigate through their network of
connections in both directions.
Conclusion
In conclusion, linked lists are a powerful and versatile data structure that plays a
crucial role in various computing applications. Unlike arrays, linked lists offer
dynamic memory allocation, meaning they can grow or shrink in size as needed,
making them more flexible in scenarios where the size of the data is unpredictable.
This dynamic nature eliminates the problem of memory wastage, commonly
associated with static data structures like arrays.
One of the key advantages of linked lists is the efficiency they provide in terms of
insertion and deletion operations. Since nodes can be added or removed without the
need to shift elements, linked lists are particularly useful in applications that require
frequent modifications to the data, such as real-time systems or operating system
process scheduling. Furthermore, linked lists can represent complex structures like
graphs and polynomial equations with ease. However, linked lists also have
limitations. The primary drawback is the increased memory overhead due to the
need for storing pointers in addition to the actual data. This can lead to inefficiency,
especially when dealing with large datasets. Additionally, linked lists do not support
efficient random access to elements, requiring sequential traversal, which can
increase time complexity for certain operations. Despite these limitations, linked
lists remain a foundational concept in computer science, offering solutions to
problems where flexibility, efficient memory management, and ease of modification
are priorities.