List, Statck and Queue ADT
List, Statck and Queue ADT
• Linked List
• Array Vs Linked List
• Singly Linked List
• Doubly Linked Lists
• Circular Linked Lists-implementation - application.
• Stack and Queue: Introduction
• Implementation (static and dynamic) application
• Circular queues-application.
2
Linked List
• Linked list is a linear data structure that includes a series of connected nodes.
• Linked list can be defined as the nodes that are randomly stored in the memory.
• A node in the linked list contains two parts, i.e., first is the data part and second is the address part.
• The last node of the list contains a pointer to the null. In a linked list, every link contains a connection to another link.
• After array, linked list is the second most used data structure.
3
Why use linked list over array?
Some of the limitations of arrays –
• The size of the array must be known in advance before using it in the program.
• Increasing the size of the array is a time taking process. It is almost impossible to expand the size of the array at run time.
• All the elements in the array need to be contiguously stored in the memory. Inserting an element in the array needs shifting
of all its predecessors.
• It allocates the memory dynamically. All the nodes of the linked list are non-contiguously stored in the memory and linked
together with the help of pointers.
• In linked list, size is no longer a problem since we do not need to define its size at the time of declaration. List grows as per
the program's demand and limited to the available memory space.
4
Declaration of Linked list
• It is simple to declare an array, as it is of single type, while the declaration of linked list is a bit more typical
than array.
• Linked list contains two parts, and both are of different types, i.e., one is the simple variable, while another is
the pointer variable.
• We can declare the linked list by using the user-defined data type structure.
struct node Here, we have defined a structure named as node that contains
{ two variables –
int data; • one is data that is of integer type, and
struct node *next; • another one is next that is a pointer which contains the
} address of next node.
5
Types of Linked list
• Singly-linked list –
o Singly linked list can be defined as the collection of an ordered set of elements.
o A node in the singly linked list consists of two parts:
data part and
link part.
o Data part of the node stores actual information that is to be represented by the node, while the link part of the node stores
the address of its immediate successor.
6
Types of Linked list
7
Advantages of Linked list
The advantages of using the Linked list are given as follows -
• Dynamic data structure - The size of the linked list may vary according to the requirements. Linked list does not have a fixed
size.
• Insertion and deletion - Unlike arrays, insertion, and deletion in linked list is easier. Array elements are stored in the
consecutive location, whereas the elements in the linked list are stored at a random location. To insert or delete an element in an
array, we have to shift the elements for creating the space. Whereas, in linked list, instead of shifting, we just have to update the
address of the pointer of the node.
• Memory efficient - The size of a linked list can grow or shrink according to the requirements, so memory consumption in
linked list is efficient.
• Implementation - We can implement both stacks and queues using linked list.
8
Disadvantages of Linked list
The limitations of using the Linked list are given as follows -
Memory usage - In linked list, node occupies more memory than array. Each node of the linked list occupies two types of
variables, i.e., one is a simple variable, and another one is the pointer variable.
Traversal - Traversal is not easy in the linked list. If we have to access an element in the linked list, we cannot access it randomly,
while in case of array we can randomly access it by index. For example, if we want to access the 3rd node, then we need to traverse
all the nodes before it. So, the time required to access a particular node is large.
Reverse traversing - Backtracking or reverse traversing is difficult in a linked list. In a doubly-linked list, it is easier but requires
more memory to store the back pointer.
9
Singly linked list or One way chain
• Singly linked list can be defined as the collection of ordered set of elements. The number of elements may
vary according to need of the program.
• A node in the singly linked list consist of two parts: data part and link part. Data part of the node stores actual
information that is to be represented by the node while the link part of the node stores the address of its
immediate successor.
• Singly linked list can be traversed only in one direction. In other words, we can say that each node contains
only next pointer, therefore we can not traverse the list in the reverse direction.
10
Operations performed on Linked list
The basic operations that are supported by a list are mentioned as follows –
Traverse – It is performed to visit each node of the list at least once in order to perform some specific operation on it
Search - It is performed to search an element from the list using the given key.
11
Operations on Singly Linked List
1. Node Creation
struct node
{
int data;
struct node *next;
};
struct node *head, *ptr;
ptr = (struct node *)malloc(sizeof(struct node *));
12
Operations on Singly Linked List
2. Insertion
The insertion into a singly linked list can be performed at different positions. Based on the position of the new
node being inserted, the insertion is categorized into the following categories.
SN Operation Description
It involves inserting any element at the front of the list. We just need to a few link
2.1 Insertion at beginning
adjustments to make the new node as the head of the list.
It involves insertion at the last of the linked list. The new node can be inserted as the only
2.2 Insertion at end of the list node in the list or it can be inserted as the last one. Different logics are implemented in
each scenario.
Insertion after specified It involves insertion after the specified node of the linked list. We need to skip the desired
2.3
node number of nodes in order to reach the node after which the new node will be inserted.
13
Steps to insert node at the beginning
1. Create a new node
3. Make the new node as the head node, i.e. now head
node will point to newNode
14
Steps to insert node at the end
1. Create a new node and make sure that the address
part of the new node points to NULL i.e. newNode-
>next=NULL
15
Algorithm to insert node at the beginning
Being:
createSinglyLinkedList (head)
alloc (newNode)
If (newNode == NULL) then
write ('Unable to allocate memory')
End if
Else then
read (data)wo
newNode.data ← data
newNode.next ← head
head ← newNode
End else
End
16
Algorithm to insert node at the End
Begin:
createSinglyLinkedList (head)
alloc (newNode)
If (newNode == NULL) then
write ('Unable to allocate memory')
End if
Else then
read (data)
newNode.data ← data
newNode.next ← NULL
temp ← head
While (temp.next != NULL) do
temp ← temp.next
End while
temp.next ← newNode
End else
End
17
Steps to insert node at the Middle
1. Create a new node
18
Algorithm to insert node at the Middle
%% Input : n position to insert data in the list
Begin:
createSinglyLinkedList (head)
alloc (newNode)
If (newNode == NULL) then
write ('Unable to allocate memory.')
End if
Else then
read (data)
newNode.data ← data
temp ← head
For i ← 2 to n-1
temp ← temp.next
If (temp == NULL) then
break
End if
End for
If (temp != NULL) then
newNode.next ← temp.next
temp.next ← newNode
End if
End else
End
19
Operations on Singly Linked List
3. Deletion
The Deletion of a node from a singly linked list can be performed at different positions. Based on the position of
the node being deleted, the operation is categorized into the following categories.
SN Operation Description
It involves deletion of a node from the beginning of the list. This is the simplest operation
3.1 Deletion at beginning
among all. It just need a few adjustments in the node pointers.
It involves deleting the last node of the list. The list can either be empty or full. Different
3.2 Deletion at the end of the list
logic is implemented for the different scenarios.
It involves deleting the node after the specified node in the list. we need to skip the
3.3 Deletion after specified node desired number of nodes to reach the node after which the node will be deleted. This
requires traversing through the list.
20
Steps to delete node at the beginning
1. Copy the address of first node i.e. head node to 3. Disconnect the connection of first node to second
some temp variable say toDelete node.
2. Move the head to the second node of the linked list 4. Free the memory occupied by the first node.
i.e. head = head->next.
21
Algorithm to delete node at the beginning
22
Steps to delete node at the last
1. Traverse to the last node of the linked list keeping track
of the second last node in some temp variable say
secondLastNode.
3. Free the memory occupied by the last node
2. If the last node is the head node then make the head node
as NULL else disconnect the second last node with the last
node i.e. secondLastNode->next = NULL.
23
Algorithm to delete node at the last
%%Input : head node of the linked list
Begin:
If (head == NULL) then
write ('List is already empty')
End if
Else then
toDelete ← head
secondLastNode ← head
While (toDelete.next != NULL) do
secondLastNode ← toDelete
toDelete ← toDelete.next
End while
If (toDelete == head) then
head ← NULL
End if
Else then
secondLastNode.next ← NULL
End else
unalloc (toDelete)
End else
End
24
Steps to delete node at the Middle
1. Traverse to the nth node of the singly linked list and
also keep reference of n-1th node in some temp variable
say prevnode.
3. Free the memory occupied by the nth node i.e.
toDelete node
25
Algorithm to delete node at the middle
%%Input : head node of the linked list
n node to be deleted
Begin:
If (head == NULL) then
write ('List is already empty')
End if
Else then
toDelete ← head
prevNode ← head
For i←2 to n do
prevNode ← toDelete
toDelete ← toDelete.next
If (toDelete == NULL) then
break
End if
End for
If (toDelete != NULL) then
If (toDelete == head) then
head ← head.next
End if
prevNode.next ← toDelete.next
toDelete.next ← NULL
unalloc (toDelete)
End if
End else
End
26
Operations on Singly Linked List
SN Operation Description
In traversing, we simply visit each node of the list at least once in order to perform
4.1 Traversing some specific operation on it, for example, printing data part of each node present
in the list.
In searching, we match each element of the list with the given element. If the
4.2 Searching element is found on any of the location then location of that element is returned
otherwise null is returned. .
27
Traversing on Singly Linked List
1. Create a temporary variable for traversing. Assign reference of head node to it, say temp = head.
2. Repeat below step till temp != NULL.
3. temp->data contains the current node data. You can print it or can perform some calculation on it.
4. Once done, move to next node using temp = temp->next;.
5. Go back to 2nd step
28
Searching on Singly Linked List
Search an element in linked list is fairly similar to how you search an element in arrays.
1. Input element to search from user. Store it in some variable say keyToSearch.
2. Declare two variable one to store index of found element and other to iterate through list. Say index = 0; and
struct node *curNode = head;
3. If curNode is not NULL and its data is not equal to keyToSearch. Then, increment index and move curNode
to its next node.
4. Repeat step 3 till curNode != NULL and element is not found, otherwise move to 5th step.
5. If curNode is not NULL, then element is found hence return index otherwise -1.
29
Application of Linked List - Addition of Two Polynomials
Addition of 2 polynomials involves combining like terms present in the two polynomials.
• Addition of 2 polynomials becomes easier if the terms are arranged in descending order of their exponents
30
Procedure for Addition of Two Polynomials
Coefficient Address
Head
5 6 6 4 2 3
Poly1
Power
Poly2
8 6 3 2 4 1 5 0
Head
31
• Adding two polynomials means additions of coefficients of same power terms
• In order to do the addition, we need to compare the exponents
Algorithm:
• Repeat the following until ptr1 and ptr2 becomes NULL
• If (ptr1->expo == ptr2->expo)
Add the coefficient and insert the newly created node in the resultant linked list and make ptr1 and ptr2 point to the
next nodes
• If (ptr1->expo == ptr2->expo)
Insert the node pointed by ptr2 in the resultant linked list and make ptr2 point to the next node.
32
Head 1 ptr1
Poly1
5 6 6 4 2 3
ptr2
Head 2
Poly2
8 6 3 2 4 1 5 0
Head 3
13 6 6 4 2 3 3 2
Resultant
5 0 4 1
33
Subtraction of Two Polynomials
Algorithm??
34
Doubly Linked List
• Doubly linked list is almost similar to singly linked list except it contains two address or reference fields,
where one of the address field contains reference of the next node and other contains reference of the previous
node.
• First and last node of a linked list contains a terminator generally a NULL value, that determines the start and
end of the list. Doubly linked list is sometimes also referred as bi-directional linked list since it allows
traversal of nodes in both direction.
35
Memory representation of Doubly Linked List
36
Advantages of Doubly linked list
Doubly linked list is one of the important data structures. Here are various advantages of doubly linked list.
37
Disadvantages of Doubly linked list
Not many but doubly linked list has few disadvantages also which can be listed below:
• It uses extra memory when compared to array and singly linked list.
• Since elements in memory are stored randomly, hence elements are accessed sequentially no direct access is
allowed.
• Doubly linked list can be used in navigation systems where both front and back navigation is required.
• It is used by browsers to implement backward and forward navigation of visited web pages i.e. back and
forward button.
• It is also used by various application to implement Undo and Redo functionality.
38
Operations on doubly linked list
The major operations performed on doubly linked list are:
39
Creating a node and Traversing on doubly linked list
Traversing
Creating a node
40
Insert node at the beginning of doubly linked list
Point the next pointer of the new node to the first node and point the previous pointer of the current first node to
the new node. Point previous of new node to NULL. The new node is now the first node of the linked list.
41
Insert node at the beginning of doubly linked list
%% Input : head {A pointer pointing to the first node of the list}
Begin:
alloc (newNode)
If (newNode == NULL) then
write ('Unable to allocate memory')
End if
Else then
read (data)
newNode.data ← data;
newNode.prev ← NULL;
newNode.next ← head;
head.prev ← newNode;
head ← newNode;
write('Node added successfully at the beginning of List')
End else
End
42
Insert node at the end of doubly linked list
To add the node in the last position, point the next pointer of the last node to the new node and point the
previous pointer of the new node to the current last node. Point the next of the new node to null.
43
Insert node at the end of doubly linked list
%% Input : last {Pointer to the last node of doubly linked list}
Begin:
alloc (newNode)
If (newNode == NULL) then
write ('Unable to allocate memory')
End if
Else then
read (data)
newNode.data ← data;
newNode.next ← NULL;
newNode.prev ← last;
last.next ← newNode;
last ← newNode;
write ('Node added successfully at the end of List')
End else
End
44
Insert node at any position of doubly linked list
If you want to add a node at the nth position, point the next pointer of the new node to the (n+1)th node and point
the previous pointer of the new node to (n-1)th node. After that, point the next of (n-1)th node and previous of
(n+1)th node to the new node.
45
Insert node at any position of doubly linked list
%% Input : head {Pointer to the first node of doubly linked list}
: last {Pointer to the last node of doubly linked list}
: N {Position where node is to be inserted}
Begin:
temp ← head
newNode.data ← data;
For i←1 to N-1 do
newNode.next ← temp.next
If (temp == NULL) then
newNode.prev ← temp
break
If (temp.next != NULL) then
End if
temp.next.prev ← newNode;
temp ← temp.next;
End if
End for
temp.next ← newNode;
If (N == 1) then
write('Node added successfully')
insertAtBeginning()
End if
End if
End
Else If (temp == last) then
insertAtEnd()
End if
Else If (temp != NULL) then
alloc (newNode)
read (data)
46
Delete node at the beginning of Doubly Linked List
Point the next pointer of the first node and the previous pointer of the second node to null.
void DeleteAtFirst()
{
Node *temp = *head;
head = temp -> next;
head -> previous = NULL;
free(temp);
}
47
Delete node at the end of Doubly Linked List
Point next pointer of the second last node and previous pointer of the last node to null.
void DeleteAtLast()
{
Node *ptr, *ptr1;
ptr = head;
while (ptr -> next != NULL)
{
ptr1 = ptr;
ptr = ptr -> next;
}
ptr1 -> next =NULL;
free ptr;
}
48
Delete node at any position in Doubly Linked List
If you want to delete the node at the nth position, point the next of (n-1)th to (n+1)th node and point the previous
of (n+1)th node to the(n-1)th node. Point previous and next of nth node to null.
49
Searching node in Doubly Linked List
Traverse from either the head of the doubly linked list or from the tale of the doubly linked list and compare the
search element to every node. If found, return true else return false.
50
Circular Linked List
• A circular linked list is a more efficient version of a singly linked list where the last node points to the first
node instead of NULL. Just like a singly linked list, here also each node has two parts.
• The first part contains data and the second part points to the next node. It contains the address of the next
node in the actual memory.
Data Next
1 “AB” 4
2
3
4 “XY” 6
5
6 “PQ” 7
7 “MN” 1
Memory Representation
51
Insert Node at the beginning of Circular Linked List
For Adding node at the beginning of the list, Unlink the last and first node and point the last node to the new
node. Now point the new node to the head node and make the new node the new head.
52
Insert node at the end of Circular Linked List
For adding a node at the end of the list, unlink the last and first node and point the last node to the new node.
Now point new node to head node.
53
Delete node at the start of Circular Linked List
Delete an existing node from the first position in the list. Point the head to the second node.
void deleteAtFirst()
{
ptr = head;
while(ptr -> next != head)
ptr = ptr -> next;
ptr->next = head->next;
free(head);
head = ptr->next;
}
54
Delete node at the last of Circular Linked List
Delete an existing node from the last position of the list. Unlink last node to head and point second last node to
head node.
void deleteAtLast()
{
ptr = head;
while(ptr ->next != head)
{
ptr1=ptr;
ptr = ptr->next;
}
ptr1->next = ptr -> next;
free(ptr);
}
55
Display Circular Linked List
Traverse through the circular linked list starting from the head and print the data in each node.
void DisplayList()
{
struct node *disp = head;
if(head != NULL)
{
while(disp -> next != disp)
{
printf("(%d, ) ",disp -> data);
disp = disp -> next;
}
}
}
56
Doubly Circular Linked List
• A doubly circular linked list is a more efficient version of a Doubly linked list. Here, 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.
• Just like a doubly-linked list, here also each node has three parts. One part contains data and the other parts
point to the next node and the previous node.
Memory Representation
57
Insert node at the beginning of Doubly Circular Linked List
Adding a node at the beginning of the list is done by pointing the new node to the first and the last node and set it
as the new head.
58
Insert node at the end of Doubly Circular Linked List
Adding a node at the end of the list is done by pointing the new node to the first and the last node.
59
Deleting node at the start of Doubly Circular Linked List
Delete an existing node from the first position in the list.
void deleteAtFirst()
{
ptr = head;
while(ptr -> next != head)
ptr = ptr -> next;
ptr->next = head->next;
free(head);
head = ptr->next;
head.previous -> ptr;
}
60
Delete node at last of Doubly Circular Linked List
Delete an existing node from the last position of the list. Unlink first and last node. Point second last node to the
first node.
void deleteAtLast()
{
ptr = head;
while(ptr ->next != head)
{
ptr1=ptr;
ptr = ptr->next;
}
ptr1->next = ptr -> next;
free(ptr);
head -> previous = ptr ;
}
61
Display Doubly Circular Linked List
Traverse through the circular linked list starting from the head and print the data in each node.
void DisplayList()
{
struct node *disp = head;
if(head != NULL)
{
while(disp -> next != disp)
{
printf("(%d, ) ",disp -> data);
disp = disp -> next;
}
}
}
62
Search for a node in a doubly circular linked list
Traverse through the circular linked list starting from the head and compare data in each node with the search
element. If found, return the location at which the element was found. If not found, return -1.
63
Advantages of Circular Linked List
• We can consider any node as a starting point. The whole linked list is traversable from any starting point.
• The time complexity for jumping from the first node to last or last to first in a doubly circular linked list is
constant
• We don’t need two different pointers for moving forward and backward. We can always reach the backward
node by moving forward since it is a loop.
64
Applications of Circular Linked list
• All applications are put in a circular list on our personal computers. The operating system gives fixed time to
each process for execution. It keeps on traversing through the list until all processes are executed.
• In multiplayer games like ludo king, all players are stored in a circular list and the pointer keeps on moving
after each player’s chance.
65
Happy Learning
66