Linked List1
Linked List1
Linked List is a linear data structure, in which elements are not stored at a contiguous
location, rather they are linked using pointers.
Linked List forms a series of connected nodes, where each node stores the data and
the address of the next node.
Linked List can be defined as collection of objects called nodes that are randomly
stored in the memory.
A node contains two fields i.e. data stored at that particular address and the pointer
which contains the address of the next node in the memory.
The last node of the list contains pointer to the null.
Till now, we were using array data structure to organize the group of elements that are to
be stored individually in the memory. However, Array has several advantages and
disadvantages which must be known in order to decide the data structure which will be
used throughout the program.
Array contains following limitations:
1. The size of array must be known in advance before using it in the program.
2. Increasing size of the array is a time taking process. It is almost impossible to expand
the size of the array at run time.
3. All the elements in the array need to be contiguously stored in the memory. Inserting
any element in the array needs shifting of all its predecessors.
Linked list is the data structure which can overcome all the limitations of an array. Using
linked list is useful because,
1. It allocates the memory dynamically. All the nodes of linked list are non-contiguously
stored in the memory and linked together with the help of pointers.
2. Sizing 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.
Ease of Insertion/Deletion: The insertion and deletion of elements are simpler than
arrays since no elements need to be shifted after insertion and deletion, Just the
address needed to be updated.
Efficient Memory Utilization: As we know Linked List is a dynamic data structure the
size increases or decreases as per the requirement so this avoids the wastage of
memory. The list is not required to be contiguously present in the memory. The node
can reside anywhere in the memory and linked together to make a list. This achieves
optimized utilization of space.
Implementation: Various advanced data structures can be implemented using a
linked list like a stack, queue, graph, hash maps, etc.
List size is limited to the memory size and doesn't need to be declared in advance.
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. For
example, to delete 1010 in id[], everything after 1010 has to be moved due to this so much
work is being done which affects the efficiency of the code.
1. Singly-linked list:
In a singly linked list, each node contains a reference to the next node in the sequence.
Traversing a singly linked list is done in a forward direction.
struct node
{
int data;
struct node *next;
};
1 Insertion at It involves inserting any element at the front of the list. We just need
beginning to a few link adjustments to make the new node as the head of the
list.
2 Insertion at end It involves insertion at the last of the linked list. The new node can be
of the list inserted as the only node in the list or it can be inserted as the last
one. Different logics are implemented in each scenario.
3 Insertion after It involves insertion after the specified node of the linked list. We
specified node need to skip the desired number of nodes in order to reach the node
after which the new node will be inserted.
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
1 Deletion at It involves deletion of a node from the beginning of the list. This is the
beginning simplest operation among all. It just need a few adjustments in the
node pointers.
2 Deletion at the It involves deleting the last node of the list. The list can either be empty
end of the list or full. Different logic is implemented for the different scenarios.
3 Deletion after It involves deleting the node after the specified node in the list. we
specified node need to skip the desired number of nodes to reach the node after which
the node will be deleted. This requires traversing through the list.
4 Traversing In traversing, we simply visit each node of the list at least once in order
to perform some specific operation on it, for example, printing data
part of each node present in the list.
5 Searching In searching, we match each element of the list with the given element.
If the element is found on any of the location then location of that
element is returned otherwise null is returned.
2. Doubly-linked list:
In a doubly linked list, each node contains references to both the next and previous nodes.
This allows for traversal in both forward and backward directions, but it requires additional
memory for the backward reference.
A node in doubly linked list is represented as:
struct node {
int data;
struct node *next;
struct node *prev;
};
Insertion: Adding a new node to a linked list involves adjusting the pointers of the existing
nodes to maintain the proper sequence. Insertion can be performed at the beginning, end,
or any position within the list.
Deletion: Removing a node from a linked list requires adjusting the pointers of the
neighbouring nodes to bridge the gap left by the deleted node. Deletion can be performed
at the beginning, end, or any position within the list.
Searching: Searching for a specific value in a linked list involves traversing the list from the
head node until the value is found or the end of the list is reached.