What are Linked Lists
A linked list is a linear
data structure.
Nodes make up linked
lists.
Nodes are structures
made up of data and a
pointer to another node.
Usually the pointer is
called next.
Arrays Vs Linked Lists
Arrays Linked list
Fixed size: Resizing is expensive Dynamic size
Insertions and Deletions are inefficient: Elements Insertions and Deletions are efficient: No shifting
are usually shifted
Random access i.e., efficient indexing No random access
Not suitable for operations requiring
accessing elements by index such as sorting
No memory waste if the array is full or almost Since memory is allocated dynamically(acc. to
full; otherwise may result in much memory our need) there is no waste of memory.
waste.
Sequential access is faster [Reason: Elements in Sequential access is slow [Reason: Elements not
contiguous memory locations] in contiguous memory locations]
Types of lists
There are two basic types of linked list
Singly Linked list
Doubly linked list
Singly Linked List
Each node has only one link part
Each link part contains the address of the
next node in the list
Link part of the last node contains NULL
value which signifies the end of the node
Schematic representation
Here is a singly-linked list (SLL):
myList
a b c d
• Each node contains a value(data) and a
pointer to the next node in the list
• myList is the header pointer which
points at the first node in the list
Basic Operations on a list
• Creating a List
• Inserting an element in a list
• Deleting an element from a list
• Searching a list
• Reversing a list
Creating a node
class Node {
int data; // A simple node of a linked list
Node next; // Pointer to the next node
// Constructor to initialize a node
Node(int data) {
this.data = data;
this.next = null; // Initialize next to null
}
}
public class LinkedList {
Node start; // Start points at the first node
// Constructor to initialize the linked list
public LinkedList() {
start = null; // Initialized to null at the beginning
}
// Method to create a new node
public Node create(int num) {
Node ptr = new Node(num); // Memory allocated
dynamically
// No need to check for memory overflow in Java
return ptr; // Return the new node
}
To be called from main() as:-
public static void main(String[] args) {
// Create a linked list
LinkedList list = new LinkedList();
// Create a new node with num = 1
Node newNode = list.create(1);
}
}
Inserting the node in a SLL
There are 3 cases here:-
Insertion at the beginning
Insertion at the end
Insertion after a particular node
Insertion at the beginning
There are two steps to be followed:-
a) Make the next pointer of the node point
towards the first node of the list
b) Make the start pointer point towards this
new node
If the list is empty simply make the start
pointer point towards the new node;
public void insertBeg(Node p) {
if (start == null) { // if the list is empty
start = p;
System.out.println("\nNode inserted successfully at the beginning");
} else {
Node temp = start;
start = p;
p.next = temp; // making new node point at the first node of the list
}
}
Inserting at the end
Here we simply need to make the next
pointer
of the last node point to the new node
public void insertEnd(Node p) {
Node temp = start;
if (start == null) {
start = p;
System.out.println("\nNode inserted
successfully at the end...!!!\n");
} else {
while (temp.next != null) {
temp = temp.next;
}
temp.next = p;
}
}
Inserting after an element
Here we again need to do 2 steps :-
Make the next pointer of the node to be
inserted point to the next node of the node
after which you want to insert the node
Make the next pointer of the node after
which the node is to be inserted, point to
the node to be inserted
public void insertAfter(int c, Node p) {
Node temp = start;
for (int i = 1; i < c; i++) {
temp = temp.next;
if (temp == null) {
System.out.println("Less than " + c + " nodes in the
list...!!!");
return; // Exit the method if there are not enough
nodes
}
}
p.next = temp.next;
temp.next = p;
System.out.println("\nNode inserted successfully");
}
Deleting a node in SLL
Here also we have three cases:-
Deleting the first node
Deleting the last node
Deleting the intermediate node
Deleting the first node
Here we apply 2 steps:-
Making the start pointer point towards the 2nd
node
Deleting the first node using delete keyword
start
one two three
public void delFirst() {
if (start == null) {
System.out.println("\nError... List is empty\
n");
} else {
Node temp = start;
start = temp.next;
System.out.println("\nFirst node deleted
successfully...!!!");
}
}
Deleting the last node
Here we apply 2 steps:-
Making the second last node’s next
pointer point to NULL
Deleting the last node via delete keyword
start
node1 node2 node3
public void delLast()
{
if (start == null) { // Check if the list is empty
System.out.println("\nError... The list is already empty.");
}
else if (start.next == null) {
// Case when the list contains only one node
start = null; // Set start to null to indicate the list is now empty
System.out.println("\nLast node deleted successfully (only
node in list)."); } else {
// Case when the list contains more than one node
Node temp = start; // Traverse to the second to last node
while (temp.next.next != null)
temp = temp.next; // Move to the next node
temp.next = null;
// Remove the last node by setting next of second to last to null
System.out.println("\nLast node deleted
Deleting a particular node
Here we make the next pointer of the node
previous to the node being deleted ,point to the
successor node of the node to be deleted and
then delete the node using delete keyword
node1 node2 node3
To be deleted
public void del(int c) {
if (c < 1) {
System.out.println("Invalid position. Position must be greater than 0.");
return; }
if (start == null) {
System.out.println("\nError... The list is already empty.");
return; }
if (c == 1) {
start = start.next;
System.out.println("Deleted Successfully from position " + c);
return; }
Node temp = start;
Node previous = null;
for (int i = 1; i < c; i++) {
previous = temp;
temp = temp.next;
if (temp == null && i < c - 1) {
System.out.println("\nNode not found at position " + c + "\n");
return; } }
if (previous != null && temp != null) {
previous.next = temp.next;
System.out.println("Deleted Successfully from position " + c); }}
Searching a SLL
Searching involves finding the required
element in the list
We can use various techniques of searching
like linear search or binary search where
binary search is more efficient in case of
Arrays
But in case of linked list since random access
is not available it would become complex to do
binary search in it
We can perform simple linear search traversal
In linear search each node is traversed till the
data in
the node matches with the required value
public void search(int x) {
Node temp = start;
while (temp != null) {
if (temp.data == x) {
System.out.println("FOUND " + temp.data);
return; // Exit the method once the item is found
}
temp = temp.next;
}
System.out.println("NOT FOUND " + x);
// Notify if the item is not found
}
Reversing a linked list
• We can reverse a linked list by reversing
the direction of the links between 2 nodes
We make use of 3 structure pointers say p,q,r
At any instant q will point to the node next to
p and r will point to the node next to q
Head P q
p rq NULL
NULL
• For next iteration p=q and q=r
• At the end we will change head to the last
public void reverse() {
Node p, q, r;
if (start == null) {
System.out.println("\nList is empty\n");
return;
}
p = start;
q = p.next;
p.next = null;
while (q != null) {
r = q.next;
q.next = p;
p = q;
q = r;
}
start = p;
System.out.println("\nReversed successfully");