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

Module 4 Notes.docx

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

Module 4 Notes.docx

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

Module 4

Linked List
Linked List
A linked list is a sequence of data structures, which are connected together via links. Linked List is a
sequence of links which contains items. Each link contains a connection to another link. Linked list is
the second most-used data structure after array. Following are the important terms to understand the
concept of Linked List.
●​ 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.
●​ LinkedList − A Linked List contains the connection link to the first
link called First.

Linked List Representation


Linked list can be visualized as a chain of nodes, where every node points to the next node.

As per the above illustration, following are the important points to be considered.
●​ Linked List contains a link element called first.
●​ 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.
●​ Last link carries a link as null to mark the end of the list.

Link list Vs Array

Feature Array Linked List


Fixed size, continuous Dynamic size, uses separate memory
Memory Allocation
memory blocks
Cannot change size after
Size Flexibility Can grow or shrink as needed
creation
Slow (requires shifting
Insertion & Deletion Fast (just update pointers)
elements)
Fast (direct access using
Access Time Slow (must go step by step)
index)
Uses less memory (no extra
Memory Usage Uses more memory (stores pointers)
pointers)
Searching Faster (can use index) Slower (must check each element)

Data Storage Stores only values Stores values + pointers to next node
Implementation Complexity Simple and easy to use More complex due to pointers

Better (stores data in a


Cache Friendliness Worse (data is scattered in memory)
sequence)

One-dimensional,
Types Available Singly, Doubly, Circular Linked List
two-dimensional, etc.

Size is fixed, and random


Best Used When Frequent insertions/deletions are required
access is needed

Good if data is small and


Performance in Large Data Better for dynamic and large data
predictable

Types of Linked List


Following are the various types of linked lists.
●​ Simple Linked List − Item navigation is forward only.
●​ Doubly Linked List − Items can be navigated forward and backward.
●​ Circular Linked List − Last item contains link of the first element as next

Basic Operations
Following are the basic operations supported by a list.
●​ Insertion − Adds an element at the beginning of the list.
●​ Deletion − Deletes an element at the beginning of the list.
●​ Display − Displays the complete list.
●​ Search − Searches an element using the given key.
●​ Delete − Deletes an element using the given key.

Insertion Operation
Adding a new node in the 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.
Imagine​ that​ we​ are​ inserting​ a​ node B (NewNode),​ between A (LeftNode)
and C (RightNode). Then point B.next to C −

It should look like this −

Now, the next node at the left should point to the new node.

This will put the new node in the middle of the two. The new list should look like this −

Similar steps should be taken if the node is being inserted at the beginning of the list. While
inserting it at the end, the second last node of the list should point to the new node and the new
node will point to NULL.
Deletion Operation
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.

The left (previous) node of the target node now should point to the next node of the target
node −

This will remove the link that was pointing to the target node. Now, using the following
code, we will remove what the target node is pointing at.

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.

Reverse Operation
This operation is a thorough one. We need to make the last node to be pointed by the head
node and reverse the whole linked list.
First, we traverse to the end of the list. It should be pointing to NULL. Now, we shall make
it point to its previous node −

We have to make sure that the last node is not the lost node. So we'll have some temp node,
which looks like the head node pointing to the last node. Now, we shall make all left side
nodes point to their previous nodes one by one.

Except the node (first node) pointed by the head node, all nodes should point to their predecessor,
making them their new successor. The first node will point to NULL.

We'll make the head node point to the new first node by using the temp node.

The linked list is now reversed.

Update Operation
The update operation in a singly linked list is used to modify the data of an existing node without changing
its structure or links.

Steps for Updating a Node

1.​ Traverse the list to locate the node at a given position.


2.​ Change the data stored in that node.
3.​ If the position is invalid, return an error message.

Copying Operation
The copying operation creates a duplicate of an existing linked list, where each node in the new list has the
same data as the corresponding node in the original list.

Steps for Copying a Singly Linked List

1.​ Create a new list with an empty head.


2.​ Traverse the original list.
3.​ For each node, create a new node with the same data and insert it into the new list.
4.​ Maintain the same order as the original list.

Doubly Linked List


A Doubly Linked List (DLL) contains an extra pointer, typically called previous pointer, together with next
pointer and data which are there in singly linked list.

A doubly linked list is a data structure that consists of a set of nodes, each of which contains a value and two
pointers, one pointing to the previous node in the list and one pointing to the next node in the list. This
allows for efficient traversal of the list in both directions, making it suitable for applications where
frequent insertions and deletions are required.

Insertion
A node can be added in four ways
1)​ At the front of the DLL
2)​ After a given node.
3)​ At the end of the DLL
4)​ Before a given node.

1)​ Add a node at the front: The new node is always added before the head of the given
Linked List. And newly added node becomes the new head of DLL. For example if the given Linked
List is A B C D and we add an item E at the front, then the Linked List becomes E A B C D. Let us
call the function that adds at the front of the list is push(). The push() must receive a pointer to the
head pointer, because push must change the head pointer to point to the new node
2)​Add a node after a given node.:
Given a pointer to a node as prev_node, and the new node is inserted after the given node.

3)​Add a node at the end:


The new node is always added after the last node of the given Linked List. For example if
the given DLL is A B C D and we add an item E at the end, then the DLL becomes A B C D
E. Since a Linked List is typically represented by the head of it, we have to traverse the list
till end and then change the next of last node to new node.

4)​Add a node before a given node:


Let the pointer to this given node be next_node and the data of the new node to be added as new_data.

1.​ ​ Check if the next_node is NULL or not. If it’s NULL, return from the function
because any new node can not be added before a NULL
2.​ Allocate memory for the new node, let it be called new_node
3.​ Set new_node->data = new_data
4.​ ​ Set the previous pointer of this new_node as the previous node of the next_node,
new_node->prev = next_node->prev
5.​ ​ Set the previous pointer of the next_node as the new_node, next_node->prev =
new_node
6.​ ​ Set the next pointer of this new_node as the next_node, new_node->next =
next_node;
7.​ ​ If the previous node of the new_node is not NULL, then set the next pointer of this
previous node as new_node, new_node->prev->next = new_node

Deletion
1) Deletion at the Beginning in Doubly Linked List
2) Deletion after a given node in Doubly Linked List
3) Deletion at a specific position in Doubly Linked List
4) Deletion at the End in Doubly Linked List
1) Deletion at the Beginning in Doubly Linked List
To update the head of a doubly linked list, follow these steps:
●​ Move the head to the next node in the list.
●​ If the new head is not empty (not NULL), set its previous pointer to NULL so that it no longer
points to the old head.

2) Deletion after a given node in Doubly Linked List

To delete a node after a specific node in a doubly linked list, follow these steps:
Find the Given Node:
●​ Look for the node that has the value you are given and store it in a variable called curr.
Check if There is a Next Node:
●​ If curr does not have a next node, there is nothing to delete, so just stop.
Find the Node to Delete:
●​ Store the next node (the one to be deleted) in a variable called nodeDelete.
Skip the Node to Be Deleted:
●​ Change curr’s next pointer to skip nodeDelete and point to the next node after it.
Fix the Backward Link (If Needed):
●​ If nodeDelete has another node after it, update its prev pointer to point back to curr.
Delete the Node:
●​ Free up the memory used by nodeDelete so it doesn’t take up space.

3) Deletion at a specific position in Doubly Linked List


Find the Node to Delete:
●​ Start from the first node (head) and move forward until you reach the position you want.
●​ Make sure the position is valid (not beyond the list size).
Adjust the Links to Remove the Node:
●​ If the node is not the first node, change the previous node's next pointer to skip the node.
●​ If the node is not the last node, change the next node's prev pointer to skip the node.
Delete the Node:
●​ Free the memory used by the node so it doesn't take up space.
4) Deletion at the End in Doubly Linked List :
Check if the List is Empty:
●​ If there are no nodes in the list, there is nothing to delete, so just stop.
Find the Last Node:
●​ Move to the last node of the list and store it in a variable called curr.
Update the Second-to-Last Node:
●​ Change the second-to-last node’s next pointer to NULL to remove the last node.
Delete the Last Node:
●​ Free up the memory used by curr so it doesn’t take up space

​ Difference between Singly Linked list and Doubly Linked List.


Feature Singly Linked List (SLL) Doubly Linked List (DLL)
Each node has two pointers: one
Each node has one pointer (next) (next) pointing to the next node and
1. Pointers
pointing to the next node. one (prev) pointing to the previous
node.

Can be traversed in only one Can be traversed in both directions


2. Traversal
direction (forward). (forward and backward).

Uses less memory since it has only Uses more memory because each
3. Memory Usage
one pointer per node. node has two pointers.

Inserting or deleting a node in the


4. Complexity of Insertion Requires updating two pointers,
middle requires updating only one
& Deletion making it slightly more complex.
pointer.

Cannot be traversed in reverse Can be easily traversed in reverse


5. Reverse Traversal
without extra storage. using the prev pointer.

Searching takes O(n) time, but


6. Search Time Searching takes O(n) time in both. backward traversal can help in
some cases.

Requires traversing the list to find Can be done quickly if a tail


7. Insertion at End
the last node. pointer is maintained.

Traversing is required to find the Can be done in constant time (O(1))


8. Deletion of Last Node
second-last node before deleting. if a tail pointer exists.

Used in complex applications like


Used in simple applications like
undo/redo operations, navigation
9. Applications stacks and basic memory
systems, and doubly linked lists in
management.
databases.
More efficient in terms of
10. Efficiency More efficient in terms of space. operations (like bidirectional
traversal).
Less flexible due to one-directional More flexible because of two-way
11. Flexibility
movement. traversal.
12. Implementation Easier to implement due to a single Slightly harder to implement due to
Complexity pointer. two pointers per node.

Update Operation
The update operation modifies the data of an existing node without altering its structure or links.
Steps for Updating a Node in DLL
1.​ Traverse the list to find the node at a given position.
2.​ Change the data of that node.
3.​ If the position is invalid, return an error.

Copying Operation in a Doubly Linked List


The copying operation creates an exact duplicate of a DLL with separate memory for each node.

Steps for Copying a Doubly Linked List


1.​ Create a new empty list.
2.​ Traverse the original list.
3.​ For each node in the original list:
o​ Create a new node with the same data.
o​ Set up next and prev pointers accordingly.
4.​ Maintain the same order as the original list.

Circular linked list

Circular Linked List


Circular linked list is a linked list where all nodes are connected to form a circle. There is no NULL at
the end. A circular linked list can be a singly circular linked list or doubly circular linked list.

Advantages of Circular Linked Lists:


1)​ Any node can be a starting point. We can traverse the whole list by starting from any
point. We just need to stop when the first visited node is visited again.
2)​ Useful for implementation of the queue. Unlike this implementation, we don’t need
to maintain two pointers for front and rear if we use a circular linked list. We can maintain a
pointer to the last inserted node and front can always be obtained as next or last.
3)​ Circular lists are useful in applications to repeatedly go around the list. For example,
when multiple applications are running on a PC, it is common for the operating system to
put the running applications on a list and then to cycle through them, giving each of them a
slice of time to execute, and then making them wait while the CPU is given to another
application. It is convenient for the operating system to use a circular list so that when it
reaches the end of the list it can cycle around to the front of the list.
4)​ Circular Doubly Linked Lists are used for implementation of advanced data
structures like Fibonacci Heap.

Real time examples:

●​ Music and video playlists: Circular doubly linked lists are commonly used to implement music and video
playlists, allowing users to easily navigate between tracks and repeat the playlist once the last track is
reached.
●​ Browser history: Browser history can be stored using a circular doubly linked list, allowing users to
navigate back and forth between previously visited pages.
●​ Undo/redo functionality: Many applications use circular doubly linked lists to implement undo/redo
functionality, allowing users to undo or redo previous actions in the application.

Implementation of stack and queue using Linked list:

Implementation of stack using Linked list.

To implement a stack using a singly linked list, we need to follow a simple rule: Last In, First Out (LIFO).
This means the last item added to the stack is the first one to be removed.

A top variable is used to keep track of the top element of the stack. With this concept, we can perform the
following operations:

Here’s how the stack operations work in simple terms:

1.​ push() – Adds a new element to the stack. This means inserting a new element at the beginning of the
linked list.
2.​ pop() – Removes the top element from the stack. This is done by deleting the first element of the linked
list.
3.​ peek() – Shows the top element without removing it.
4.​ display() – Prints all elements in the stack.

In a stack implementation using a singly linked list, we use a top pointer to keep track of the top element.

●​ The top is like the head of the list, where we add (push) and remove (pop) elements.
●​ The first node has null in its link field because there is no node before it.
●​ Each new node stores the address of the previous top node in its link field.
●​ The last added node is always at the top, and its address is stored in the top pointer.

This way, the stack follows the Last In, First Out (LIFO) rule.
Implementation of queue using Linked list:

Have you ever thought about how to manage data in the same order it arrives? A queue is a simple way to do this
using the First In, First Out (FIFO) method.

Using a linked list to create a queue makes it flexible and memory-efficient. It helps in handling tasks in order, like
managing resources or processing requests one by one.

A queue follows the FIFO rule, meaning the first item added is the first one to be removed. It has two main
operations:

1.​ Enqueue – Adds an element to the end of the queue.


2.​ Dequeue – Removes an element from the front of the queue.

Enqueue Operation (Inserting an Element) in a Linked List-Based Queue


Creating a New Node in a Queue
1.​ When adding (enqueueing) an element, first create a new node (let’s call it NEW_NODE).
2.​ Use two pointers, FRONT and REAR, to track the first and last elements of the queue.

o​ When the queue is empty, both should be NULL (this is done only once during initialization, not for every
enqueue).

Setting Up the New Node


1.​ Store the value (let’s call it DATA) inside NEW_NODE.
2.​ Set the next pointer of NEW_NODE to NULL (since it's the last node for now).

Enqueue Operation (Adding an Element)


1.​ Check if the queue is empty (FRONT is NULL):
o​ If empty → Set FRONT and REAR to NEW_NODE (since it’s the only node in the queue).
2.​ If the queue is not empty (FRONT is not NULL):

o​ Link the current last node (REAR) to NEW_NODE.


o​ Update REAR to point to NEW_NODE (making it the new last node).

Dequeue Operation (Removing an Element) in a Linked List-Based Queue


The dequeue operation removes an element from the front of the queue, following the First In, First Out (FIFO)
rule.
Steps to Perform Dequeue
1.​ Check if the queue is empty

o​ If FRONT is NULL, the queue is empty. Print a message like "Queue is empty! Nothing to dequeue."
2.​ If the queue is not empty:

o​ Store the current FRONT node in a temporary variable (TEMP).


o​ Move FRONT to the next node (FRONT = FRONT → next).
o​ Free the memory of the old front node (TEMP).
3.​ If the queue becomes empty after removing the node:

o​ Set REAR to NULL (since there are no elements left).

Reversing a singly linked list.


Reversing a Linked List Using Three Pointers
To reverse a linked list, we change the direction of the links using three pointers:

1.​ prev – Keeps track of the previous node.


2.​ curr – Keeps track of the current node.
3.​ next – Keeps track of the next node.

Steps to Reverse the Linked List:


1.​ Start with the first node:
o​ Set curr to the head of the list.
o​ Set next to the node after curr.
2.​ Change the link direction:

o​ Make curr point to prev instead of the next node.


3.​ Move all three pointers forward:

o​ Set prev to curr.


o​ Set curr to next.
4.​ Repeat until curr becomes NULL.

At the end, prev will be the new head of the reversed linked list.

You might also like