Unit3
Unit3
► A linked list is a linear data structure, in which the elements are not stored at
contiguous memory locations. The elements in a linked list are linked using
pointers as shown in the below image:
2
Why Linked List?
Example:
In a system, if we maintain a sorted list of IDs in an array id[] = [1000, 1010, 1050, 2000, 2040].
If we want to insert a new ID 1005, then to maintain the sorted order, we have to move all the
elements after 1000 (excluding 1000).
Deletion is also expensive with arrays until unless some special techniques are used.
3
Advantages of Linked Lists over arrays:
● Dynamic Array.
● Ease of Insertion/Deletion.
4
Drawbacks of Linked Lists:
5
Types of Linked Lists:
● Single Linked List – In this type of linked list, one can move or traverse the linked
list in only one direction
● Doubly Linked List – In this type of linked list, one can move or traverse the
linked list in both directions (Forward and Backward)
● Circular Linked List – In this type of linked list, the last node of the linked list
contains the link of the first/head node of the linked list in its next pointer and the
first/head node contains the link of the last node of the linked list in its prev pointer
6
Basic operations on Linked Lists:
● Deletion
● Insertion
● Search
● Display
7
Representation of Linked Lists:
A linked list is represented by a pointer to the first node of the linked list.
The first node is called the head of the linked list. If the linked list is
empty, then the value of the head points to NULL.
8
Inserting a node
# Node class
class Node:
10
Add a node at the front: (4 steps process)
Approach: The new node is always added before the head of the given Linked List.
And newly added node becomes the new head of the Linked List. For example, if the
given Linked List is 10->15->20->25 and we add an item 5 at the front, then the Linked
List becomes 5->10->15->20->25. 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 the push
must change the head pointer to point to the new node
11
Following are the 4 steps to add a node at the front.
● Time Complexity: O(1), We have a pointer to the head and we can directly
attach a node and change the pointer. So the Time complexity of inserting a
node at the head position is O(1) as it does a constant amount of work.
● Auxiliary Space: O(1)
13
Add a node after a given node: (5 steps process)
Approach: We are given a pointer to a node, and the new node is inserted after the
given node.
Follow the steps to add a node after a given node:
14
15
#This function is in LinkedList class.
# Inserts a new node after the given prev_node. This method is
# defined inside LinkedList class shown above */
17
Add a node at the end: (6 steps process)
● The new node is always added after the last node of the given Linked List. For
example if the given Linked List is 5->10->15->20->25 and we add an item 30 at
the end, then the Linked List becomes 5->10->15->20->25->30.
● Since a Linked List is typically represented by the head of it, we have to traverse
the list till the end and then change the next to last node to a new node.
18
19
# This function is defined in Linked List class
# Appends a new node at the end. This method is
# defined inside LinkedList class shown above
def append(self, new_data):
# 1. Create a new node
# 2. Put in the data
# 3. Set next as None
new_node = Node(new_data)
# 4. If the Linked List is empty, then make the
# new node as head
if self.head is None:
self.head = new_node
return
# 5. Else traverse till the last node
last = self.head
while (last.next):
last = last.next
20
# 6. Change the next of last node
last.next = new_node
# This function is defined in Linked List class
# Appends a new node at the end. This method is
# defined inside LinkedList class shown above
def append(self, new_data):
# 1. Create a new node
# 2. Put in the data
# 3. Set next as None
new_node = Node(new_data)
# 4. If the Linked List is empty, then make the
# new node as head
if self.head is None:
self.head = new_node
return
# 5. Else traverse till the last node
last = self.head
while (last.next):
last = last.next
# 6. Change the next of last node
last.next = new_node
21
Complexity Analysis:
● Time complexity: O(N), where N is the number of nodes in the linked list. Since there
is a loop from head to end, the function does O(n) work.
○ This method can also be optimized to work in O(1) by keeping an extra pointer
to the tail of the linked list/
● Auxiliary Space: O(1)
22
Deleting a node
23
1) Delete from Beginning:
24
2) Delete from End:
27
Applications, Advantages and Disadvantages of Linked List
● A Linked List is a linear data structure that is used to store a collection of data with the help of
nodes. A linked list is made up of two items that are data and a reference to the next node. A
reference to the next node is given with the help of pointers and data is the value of a node.
Each node contains data and links to the other nodes. It is an ordered collection of data
elements called a node and the linear order is maintained by pointers. It has an upper hand
over the array as the number of nodes i.e. the size of the linked list is not fixed and can grow
and shrink as and when required, unlike arrays. Some of the features of the linked list are as
follows:
● The consecutive elements are connected by pointers.
● The size of a linked list is not fixed.
● The last node of the linked list points to null.
● Memory is not wasted but extra memory is consumed as it also uses pointers to keep track of
the next successive node.
● The entry point of a linked list is known as the head.
28
The various types of linked lists are as follows:
● Singly Linked List: It is the most basic linked list in which traversal is unidirectional i.e.
from the head node to the last node.
● Doubly Linked List: In this linked list, traversal can be done in both ways, and hence it
requires an extra pointer.
● Circular Linked List: This linked list is unidirectional but in this list, the last node points
to the first i.e. the head node and hence it becomes circular in nature.
● Circular Doubly Linked List: The circular doubly linked list is a combination of the
doubly linked list and the circular linked list. It means that this linked list is bidirectional
and contains two pointers and the last pointer points to the first pointer.
29
Linked Lists are most commonly used for:
● Linked Lists are mostly used because of their effective insertion and
deletion.
● Insertion and deletion in the linked list are very effective and take
less time complexity as compared to the array data structure.
● This data structure is simple and can be also used to implement
a stack, queues, and other abstract data structures.
30
Applications of Linked Lists:
31
Applications of Linked Lists in real world:
● The list of songs in the music player are linked to the previous and next songs.
● In a web browser, previous and next web page URLs are linked through the
previous and next buttons.
● In image viewer, the previous and next images are linked with the help of the
previous and next buttons.
● Switching between two applications is carried out by using “alt+tab” in windows
and “cmd+tab” in mac book. It requires the functionality of circular linked list.
● In mobile phones, we save the contacts of the people. The newly entered contact
details will be placed at the correct alphabetical order. This can be achieved by
linked list to set contact at correct alphabetical position.
● The modifications that we are made in the documents are actually created as
nodes in doubly linked list. We can simply use the undo option by pressing Ctrl+Z
to modify the contents. It is done by the functionality of linked list.
32
Advantages of Linked Lists:
33
Disadvantages of Linked Lists:
34
Types of Linked List
A linked list is a linear data structure, in which the elements are not stored at contiguous memory
locations. The elements in a linked list are linked using pointers. In simple words, a linked list
consists of nodes where each node contains a data field and a reference(link) to the next node in
the list.
37
Doubly Linked List
A doubly linked list or a two-way linked list is a more complex type of linked list that
contains a pointer to the next as well as the previous node in sequence.
Therefore, it contains three parts of data, a pointer to the next node, and a pointer to the
previous node. This would enable us to traverse the list in the backward direction as
well. Below is the image for the same:
38
Doubly Linked List
A Doubly Linked List (DLL) contains an extra pointer, typically called the
previous pointer, together with the next pointer and data which are
there in a singly linked list.
39
Below are operations on the given
DLL:
► Add a node at the front of DLL: The new node is always
added before the head of the given Linked List. And the newly
added node becomes the new head of DLL & maintaining a
global variable for counting the total number of nodes at that
time.
Traversal of a Doubly linked list
40
► Insertion of a node: This can be done in three ways:
► At the beginning: The new created node is insert in
before the head node and head points to the new node.
► At the end: The new created node is insert at the end of
the list and tail points to the new node.
► At a given position: Traverse the given DLL to that
position(let the node be X) then do the following:
► Change the next pointer of new Node to the next
pointer of Node X.
► Change the prev pointer of next Node of Node X to the
new Node.
► Change the next pointer of node X to new Node.
► Change the prev pointer of new Node to the Node X.
41
► Deletion of a node: This can be done in three ways:
► At the beginning: Move head to the next node to delete the node at
the beginning and make previous pointer of current head to NULL .
► At the last: Move tail to the previous node to delete the node at the end
and make next pointer of tail node to NULL.
► At a given position: Let the prev node of Node at position pos be Node
X and next node be Node Y, then do the following:
► Change the next pointer of Node X to Node Y.
► Change the previous pointer of Node Y to Node X.
42
Doubly Linked List | Set 1 (Introduction
and Insertion)
43
# Node of a doubly linked list
► class Node:
45
Disadvantages of DLL over the singly
linked list:
46
Insertion in DLL:
47
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 1->0->1->5 and we add an
item 5 at the front, then the Linked List becomes 5->1->0->1->5.
Let us call the function that adds at the front of the list push(). The
push() must receive a pointer to the head pointer because the push
must change the head pointer to point to the new node
48
# Adding a node at the front of the list
► def push(self, new_data):
► # 1 & 2: Allocate the Node & Put in the data
► new_node = Node(data=new_data)
► # 3. Make next of new node as head and previous as NULL
► new_node.next = self.head
► new_node.prev = None
► # 4. change prev of head node to new node
► if self.head is not None:
► self.head.prev = new_node
► # 5. move the head to point to the new node
► self.head = new_node
49
2) Add a node after a given node:
50
► # Given a node as prev_node, insert
► # a new node after the given node
► def insertAfter(self, prev_node, new_data):
► # 1. check if the given prev_node is NULL
► if prev_node is None:
► print("This node doesn't exist in DLL")
► return
► # 2. allocate node & 3. put in the data
► new_node = Node(data=new_data)
► # 4. Make next of new node as next of prev_node
► new_node.next = prev_node.next
► # 5. Make the next of prev_node as new_node
► prev_node.next = new_node
► # 6. Make prev_node as previous of new_node
► new_node.prev = prev_node
► # 7. Change previous of new_node's next node */
► if new_node.next is not None:
► new_node.next.prev = new_node
51
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 5->1->0->1->5->2 and
we add item 30 at the end, then the DLL becomes 5->1->0->1->5-
>2->30. Since a Linked List is typically represented by its head of it,
we have to traverse the list till the end and then change the next of
last node to the new node.
52
# Add a node at the end of the DLL
54
4) Add a node before a given node:
► Follow the below steps to solve the problem:
► Let the pointer to this given node be next_node and the data of the new node be
added as new_data.
► 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
► Allocate memory for the new node, let it be called new_node
► Set new_node->data = new_data
► Set the previous pointer of this new_node as the previous node of the next_node,
new_node->prev = next_node->prev
► Set the previous pointer of the next_node as the new_node, next_node->prev =
new_node
► Set the next pointer of this new_node as the next_node, new_node->next =
next_node;
► 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
► Else, if the prev of new_node is NULL, it will be the new head node. So, make
(*head_ref) = new_node.
55
56
Python program to insert a new node at the beginning of
the Circular Linked List
In this program, we will create a circular linked list and insert every new node
at the beginning of the list. If the list is empty, then head and tail will point to
the newly added node. If the list is not empty, then we will store the data of
the head into a temporary node temp and make new node as the head. This
new head will point to the temporary node. In simple words, the newly added
node will be the first node(head) and previous head(temp) will become the
second node of the list.
57
58
After inserting the new node to the beginning of the list.
59
ALGORITHM:
1. Define a Node class which represents a node in the list. It has two
properties data and next which will point to the next node.
2. Define another class for creating the circular linked list, and it has two
nodes: head and tail. It has two methods: addAtStart() and display() .
3. addAtStart() will add the node to the beginning of the list:
● It first checks whether the head is null (empty list), then it will insert the
node as the head.
● Both head and tail will point to a newly added node.
● If the list is not empty, then the newly added node will become the new
head, and it will point to the previous head. 60