Table of contents
1.
Introduction
2.
Examples
3.
Traversal of Singly Linked List (Iterative Approach)
4.
Step-by-Step Algorithm
5.
Examples
5.1.
C
5.2.
C++
5.3.
Java
5.4.
Python
5.5.
JavaScript
5.6.
C#
5.7.
Time Complexity
5.8.
Space Complexity
6.
Traversal of Singly Linked List (Recursive Approach)
6.1.
Step-by-Step Algorithm
7.
Examples
7.1.
C
7.2.
C++
7.3.
Java
7.4.
Python
7.5.
JavaScript
7.6.
C#
7.7.
Time Complexity
7.8.
Space Complexity
8.
Frequently Asked Questions
8.1.
Can we modify the data of nodes while traversing the linked list?
8.2.
Is it possible to traverse a linked list in reverse order?
8.3.
How do we handle an empty linked list during traversal?
9.
Conclusion
Last Updated: Oct 19, 2024
Easy

Traverse in Linked List

Author Riya Singh
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

A linked list is a linear data structure that consists of a sequence of nodes, where each node contains a data element and a reference (or link) to the next node in the sequence. Unlike arrays, linked lists do not store elements in contiguous memory locations, which allows for efficient insertion and deletion of elements at any position in the list. Traversal is an important concept for performing different tasks, like searching for a specific element, printing the contents of the list, or applying a certain operation to each node. 

Traverse in Linked List

In this article, we will talk about the concept of traversing a linked list, both iteratively and recursively. We will provide step-by-step algorithms, and code examples in different languages, and analyze the time & space complexity of each approach.

Examples

Let's consider a simple singly linked list with the following elements: 1 -> 2 -> 3 -> 4 -> 5 -> NULL. To traverse this linked list, we need to start from the head node and visit each node until we reach the end of the list (i.e., the node pointing to NULL).

For example, if we want to print the data of each node in the linked list, we would traverse the list and print the data at each node:

1
2
3
4
5


Similarly, if we want to find the maximum element in the linked list, we would traverse the list, comparing each node's data with the current maximum and updating it accordingly.

Traversal of Singly Linked List (Iterative Approach)

The iterative approach to traversing a singly linked list involves using a loop to visit each node of the list sequentially. We start from the head node and use a temporary pointer variable to keep track of the current node being visited. The temporary pointer is initially set to the head of the list and is updated to the next node in each iteration of the loop until it reaches the end of the list (i.e. when the next pointer becomes NULL).


Let’s understand this process that how it works :
 

1. Initialize a temporary pointer variable, let's call it "current," and set it to the head of the linked list.
 

2. Enter a loop that continues until "current" becomes NULL.
 

3. Inside the loop, process the data of the current node (e.g., print the data, and perform a specific operation).
 

4. Update the "current" pointer to point to the next node by assigning it the value of the next pointer of the current node.
 

5. Repeat steps 3-4 until "current" becomes NULL, indicating the end of the list has been reached.


By following these steps, we can traverse the entire linked list and access each node's data in a sequential manner.

Step-by-Step Algorithm

Let’s see a step-by-step algorithm for the iterative traversal of a singly linked list:
 

1. Initialize a pointer variable "current" to the head of the linked list.
 

2. While "current" is not NULL, do the following:
 

   a. Process the data of the current node (e.g., print the data, perform a specific operation).
 

   b. Update "current" to point to the next node by assigning it the value of the next pointer of the current node.
 

3. If "current" becomes NULL, exit the loop as the end of the list has been reached.

 

This algorithm provides a clear and concise set of steps to perform the iterative traversal of a singly linked list. It ensures that each node is visited exactly once and that the traversal continues until the end of the list is reached.

Examples

  • C
  • C++
  • Java
  • Python
  • JavaScript
  • C#

C

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* next;
};

void traverseList(struct Node* head) {
struct Node* current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}

int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;

head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));

head->data = 1;
head->next = second;

second->data = 2;
second->next = third;

third->data = 3;
third->next = NULL;

printf("Linked List: ");
traverseList(head);

return 0;
}
You can also try this code with Online C Compiler
Run Code

C++

#include <iostream>

struct ListNode {
int data;
ListNode* next;
};

void traverseList(ListNode* head) {
ListNode* current = head;
while (current != NULL) {
std::cout << current->data << " ";
current = current->next;
}
std::cout << std::endl;
}

int main() {
ListNode* head = new ListNode{1, NULL};
ListNode* second = new ListNode{2, NULL};
ListNode* third = new ListNode{3, NULL};

head->next = second;
second->next = third;

std::cout << "Linked List: ";
traverseList(head);

delete head;
delete second;
delete third;

return 0;
}
You can also try this code with Online C++ Compiler
Run Code

Java

class ListNode {
int data;
ListNode next;

public ListNode(int data) {
this.data = data;
this.next = null;
}
}

public class LinkedListTraversal {
public static void traverseList(ListNode head) {
ListNode current = head;
while (current != null) {
System.out.print(current.data + " ");
current = current.next;
}
System.out.println();
}

public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode second = new ListNode(2);
ListNode third = new ListNode(3);

head.next = second;
second.next = third;

System.out.print("Linked List: ");
traverseList(head);
}
}
You can also try this code with Online Java Compiler
Run Code

Python

class ListNode:
def __init__(self, data=0, next=None):
self.data = data
self.next = next

def traverse_list(head):
current = head
while current:
print(current.data, end=" ")
current = current.next
print()

# Create the linked list
head = ListNode(1)
second = ListNode(2)
third = ListNode(3)

head.next = second
second.next = third

print("Linked List:", end=" ")
traverse_list(head)
You can also try this code with Online Python Compiler
Run Code

JavaScript

class ListNode {
constructor(data) {
this.data = data;
this.next = null;
}
}

function traverseList(head) {
let current = head;
while (current) {
console.log(current.data);
current = current.next;
}
}

// Create the linked list
const head = new ListNode(1);
const second = new ListNode(2);
const third = new ListNode(3);

head.next = second;
second.next = third;

console.log("Linked List:");
traverseList(head);
You can also try this code with Online Javascript Compiler
Run Code

C#

public class ListNode
{
public int data;
public ListNode next;

public ListNode(int data)
{
this.data = data;
next = null;
}
}

public class LinkedList
{
public void TraverseList(ListNode head)
{
ListNode current = head;
while (current != null)
{
Console.Write(current.data + " ");
current = current.next;
}
Console.WriteLine();
}

static void Main(string[] args)
{
ListNode head = new ListNode(1);
ListNode second = new ListNode(2);
ListNode third = new ListNode(3);

head.next = second;
second.next = third;

Console.Write("Linked List: ");
LinkedList linkedList = new LinkedList();
linkedList.TraverseList(head);
}
}


Output

Linked List: 1 2 3 

Time Complexity

The time complexity of the iterative traversal algorithm is O(n), where n is the number of nodes in the linked list. This is because we visit each node exactly once during the traversal. The time taken is directly proportional to the size of the linked list, as we need to process each node to access its data and move to the next node.
 

In the worst case, where we need to traverse the entire linked list, the time complexity remains O(n). This is because we have to visit all n nodes to complete the traversal.

Space Complexity

The space complexity of the iterative traversal algorithm is O(1), which means it uses constant extra space. This is because we only use a single temporary pointer variable to keep track of the current node during the traversal. The space required does not depend on the size of the linked list, as we are not storing any additional data structures that grow with the input size.

The iterative traversal algorithm is space-efficient since it does not require any extra space that scales with the size of the linked list.

In summary, the iterative traversal of a singly linked list has a time complexity of O(n) and a space complexity of O(1). It provides an efficient way to visit each node of the list without requiring any additional data structures.

Traversal of Singly Linked List (Recursive Approach)

In addition to the iterative approach, we can also traverse a singly linked list using recursion. The recursive approach follows the natural recursive structure of a linked list, where each node points to the next node, and the last node points to NULL.
 

The recursive traversal algorithm works as follows:

1. Base Case: If the current node is NULL, return as there are no more nodes to process.
 

2. Recursive Case:
 

   a. Process the data of the current node (e.g., print the data, perform a specific operation).
 

   b. Recursively call the traversal function on the next node by passing `current->next` as the argument.


The recursive approach breaks down the problem into smaller subproblems. Each recursive call processes the current node and then makes a recursive call to process the remaining nodes in the list. This process continues until the base case is reached, which is when the current node becomes NULL.

Let’s understand the breakdown of the recursive traversal process:
 

1. Start with the head node of the linked list.
 

2. Check if the current node is NULL. If it is, return as there are no more nodes to process.
 

3. If the current node is not NULL:
 

   a. Process the data of the current node.
 

   b. Recursively call the traversal function on the next node by passing `current->next` as the argument.
 

4. The recursive calls will continue until the base case is reached (i.e., the current node becomes NULL).


By following these steps, the recursive traversal will visit each node of the linked list and process their data.

Note: The recursive approach provides a concise and elegant solution to traversing a linked list. It takes advantage of the recursive nature of the linked list structure, where each node points to the next node, and the last node points to NULL.

Step-by-Step Algorithm

Let’s look at a step-by-step algorithm for the recursive traversal of a singly linked list:

1. Define a recursive function, let's call it `traverseList`, that takes the head of the linked list as a parameter.
 

2. In the `traverseList` function:
 

   a. Check the base case: If the current node is NULL, return as there are no more nodes to process.
 

   b. If the current node is not NULL:
 

      - Process the data of the current node (e.g., print the data, perform a specific operation).
 

      - Recursively call the `traverseList` function on the next node by passing `current->next` as the argument.
 

3. Call the `traverseList` function with the head of the linked list to start the recursive traversal.


Let’s look at a proper representation of the recursive algorithm:

traverseList(head):
    if head is NULL:
        return
    else:
        process data of head
        traverseList(head->next)


This step-by-step algorithm outlines the recursive approach to traversing a singly linked list. The recursive function `traverseList` takes the head of the linked list as a parameter. It first checks the base case, which is when the current node becomes NULL, indicating the end of the list. If the base case is not met, the function processes the data of the current node and then makes a recursive call to `traverseList` with the next node as the argument.

The recursive calls will keep happening until the base case is reached, at which point the recursion will start unwinding, and the traversal will be complete.

Examples

  • C
  • C++
  • Java
  • Python
  • JavaScript
  • C#

C

#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* next;
};

void traverseList(struct Node* head) {
if (head == NULL) {
return;
}
printf("%d ", head->data);
traverseList(head->next);
}

int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;

head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));

head->data = 1;
head->next = second;

second->data = 2;
second->next = third;

third->data = 3;
third->next = NULL;

printf("Linked List: ");
traverseList(head);
printf("\n");

return 0;
}
You can also try this code with Online C Compiler
Run Code

C++

#include <iostream>

struct ListNode {
int data;
ListNode* next;
};

void traverseList(ListNode* head) {
if (head == NULL) {
return;
}
std::cout << head->data << " ";
traverseList(head->next);
}

int main() {
ListNode* head = new ListNode{1, NULL};
ListNode* second = new ListNode{2, NULL};
ListNode* third = new ListNode{3, NULL};

head->next = second;
second->next = third;

std::cout << "Linked List: ";
traverseList(head);
std::cout << std::endl;

delete head;
delete second;
delete third;

return 0;
}
You can also try this code with Online C++ Compiler
Run Code

Java

class ListNode {
int data;
ListNode next;

public ListNode(int data) {
this.data = data;
this.next = null;
}
}

public class LinkedListTraversal {

public static void traverseList(ListNode head) {
if (head == null) {
return;
}
System.out.print(head.data + " ");
traverseList(head.next);
}

public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode second = new ListNode(2);
ListNode third = new ListNode(3);

head.next = second;
second.next = third;

System.out.print("Linked List: ");
traverseList(head);
System.out.println();
}
}
You can also try this code with Online Java Compiler
Run Code

Python

class ListNode:
def __init__(self, data=0, next=None):
self.data = data
self.next = next

def traverse_list(head):
if head is None:
return
print(head.data, end=" ")
traverse_list(head.next)

# Create the linked list
head = ListNode(1)
second = ListNode(2)
third = ListNode(3)

head.next = second
second.next = third

print("Linked List:", end=" ")
traverse_list(head)
print()
You can also try this code with Online Python Compiler
Run Code

JavaScript

class ListNode {
constructor(data) {
this.data = data;
this.next = null;
}
}

function traverseList(head) {
if (head === null) {
return;
}
console.log(head.data);
traverseList(head.next);
}

// Create the linked list
const head = new ListNode(1);
const second = new ListNode(2);
const third = new ListNode(3);

head.next = second;
second.next = third;

console.log("Linked List:");
traverseList(head);
You can also try this code with Online Javascript Compiler
Run Code

C#

public class ListNode
{
public int data;
public ListNode next;

public ListNode(int data)
{
this.data = data;
next = null;
}
}

public class LinkedList
{
public void TraverseList(ListNode head)
{
if (head == null)
{
return;
}
Console.Write(head.data + " ");
TraverseList(head.next);
}

static void Main(string[] args)
{
ListNode head = new ListNode(1);
ListNode second = new ListNode(2);
ListNode third = new ListNode(3);

head.next = second;
second.next = third;

Console.Write("Linked List: ");
LinkedList linkedList = new LinkedList();
linkedList.TraverseList(head);
Console.WriteLine();
}
}


Output

Linked List: 1 2 3 

Time Complexity

The time complexity of the recursive traversal algorithm is O(n), where n is the number of nodes in the linked list. This is because the recursive function visits each node exactly once. The time taken is directly proportional to the size of the linked list, as the function needs to process each node to access its data and make a recursive call to the next node.

In the worst case, where the recursive function needs to traverse the entire linked list, the time complexity remains O(n). This is because the function will make n recursive calls, one for each node in the list.

Space Complexity

The space complexity of the recursive traversal algorithm is O(n) in the worst case, where n is the number of nodes in the linked list. This is because the recursive calls will be stored on the call stack, and the maximum depth of the recursion will be equal to the number of nodes in the list.

Each recursive call requires a certain amount of space on the call stack to store the function parameters, local variables, and the return address. In the worst case, when the linked list is traversed to the end, the recursion depth will reach n, and the call stack will contain n recursive calls.

It's important to note that the space complexity of O(n) is due to the recursive calls on the call stack and not because of any additional data structures used within the algorithm.

In summary, the recursive traversal of a singly linked list has a time complexity of O(n) and a space complexity of O(n) in the worst case. While the recursive approach provides a concise and elegant solution, it may not be the most space-efficient compared to the iterative approach, especially for large linked lists or in systems with limited stack space.

Frequently Asked Questions

Can we modify the data of nodes while traversing the linked list?

Yes, we can modify the data of nodes while traversing the linked list by accessing and updating the data member of each node.

Is it possible to traverse a linked list in reverse order?

Yes, it is possible to traverse a linked list in reverse order. One approach is to use recursion, where the recursive function first traverses to the end of the list and then processes the nodes in reverse order while backtracking.

How do we handle an empty linked list during traversal?

When traversing an empty linked list, the head pointer will be NULL. In the iterative approach, the loop condition will fail immediately, and in the recursive approach, the base case will be triggered, resulting in no nodes being processed.

Conclusion

In this article, we explained the concept of traversing a singly linked list using both iterative and recursive approaches. We provided step-by-step algorithms, and code examples in multiple programming languages, and analyzed the time and space complexity of each approach. Learning the concept that how to traverse a linked list is very important for performing various operations and solving problems related to linked lists that will be very helpful in your data structures related problems and concepts.

You can also check out our other blogs on Code360.

Live masterclass