Core Java

Reverse a Linked List

Greetings! This tutorial will focus on how to reverse a linked list in java.

1. Introduction

Linked lists are a popular data structure in computer science that can be used to represent sequences of elements. They consist of nodes, each containing a value and a reference to the next node in the sequence. Reversing a linked list involves changing the order of the nodes so that the last node becomes the first node, the second-to-last node becomes the second node, and so on. This operation can be useful in a variety of applications, such as sorting algorithms or data analysis. In Java, reversing a linked list can be achieved using various techniques and algorithms. In this response, we will explore some of the common approaches for reversing a linked list in Java.

1.1 Linked List Data Structure

In Java, a linked list is a linear data structure that consists of a sequence of nodes, each containing a value and a reference to the next node in the sequence. Unlike arrays, which are stored in contiguous memory locations, the nodes of a linked list can be located at different locations in memory. The basic structure of a linked list in Java consists of a head node, which represents the first node in the sequence, and a tail node, which represents the last node in the sequence. Each node in between contains a value and a reference to the next node in the sequence. There are several types of linked lists in Java, including:

  • Singly-linked list: In a singly linked list, each node has a reference to the next node in the list, but not the previous node.
  • Doubly linked list: In a doubly linked list, each node has references to both the next and previous nodes in the list, allowing for traversal in both directions.
  • Circular linked list: In a circular linked list, the last node in the list has a reference to the first node, forming a loop. This allows for continuous traversal of the list.
  • Circular doubly linked list: A combination of the circular and doubly linked list, where each node has references to both the next and previous nodes, and the last node in the list has a reference to the first node, forming a circular loop.

Each type of linked list has its unique features and use cases. For example, a singly linked list is often used when only forward traversal is needed and memory efficiency is a concern. A doubly linked list is useful when both forward and backward traversal is required, but it requires more memory. Circularly linked lists can be useful for applications that require continuous iteration of a list, while circular doubly linked lists provide both forward and backward traversal in a circular manner. Here is an example of a simple linked list implementation in Java:

Sample code

public class LinkedList {
    private Node head;

    private static class Node {
        int value;
        Node next;

        Node(int value) {
            this.value = value;
            this.next = null;
        }
    }

    public void add(int value) {
        Node newNode = new Node(value);
        if (head == null) {
            head = newNode;
            return;
        }
        Node current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = newNode;
    }

    public void print() {
        Node current = head;
        while (current != null) {
            System.out.print(current.value + " ");
            current = current.next;
        }
        System.out.println();
    }
}

This implementation defines a private inner class Node that represents a node in the linked list, with fields for the node’s value and its reference to the next node. The LinkedList class maintains a reference to the head node and provides methods for adding values to the list and printing its contents. To add a value to the list, the add() method creates a new Node object with the given value and appends it to the end of the list by traversing the list until the last node and setting its next reference to the new node. To print the contents of the list, the print() method traverses the list starting from the head node and prints each node’s value until it reaches the end of the list. Overall, linked lists provide a flexible and efficient data structure for storing and manipulating sequences of data in Java.

1.2 Iterative Algorithm Implementation

Here is an example of an iterative algorithm implementation for a singly linked list in Java:

Iterative algorithm code

public class LinkedList {
    Node head;

    static class Node {
        int data;
        Node next;

        Node(int d) {
            data = d;
            next = null;
        }
    }

    // Method to reverse the linked list iteratively
    public void reverseList() {
        Node prev = null;
        Node current = head;
        Node next = null;

        while (current != null) {
            next = current.next;
            current.next = prev;
            prev = current;
            current = next;
        }
        head = prev;
    }

    // Method to insert a new node at the beginning of the linked list
    public void insert(int newData) {
        Node newNode = new Node(newData);
        newNode.next = head;
        head = newNode;
    }

    // Method to print the linked list
    public void printList() {
        Node node = head;
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
    }

    // Main method to test the implementation
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.insert(1);
        list.insert(2);
        list.insert(3);
        list.insert(4);

        System.out.println("Original List:");
        list.printList();

        list.reverseList();

        System.out.println("\nReversed List:");
        list.printList();
    }
}

In this implementation, the reverseList() method iterates through the linked list, reversing the next pointers of each node to point to the previous node instead of the next node. This is done using three pointers: prev, current, and next. At each iteration, current.next is set to prev, and then prev, current, and next are updated to move to the next nodes in the list. The insert() method is used to add new nodes to the beginning of the linked list, and the printList() method is used to print the list. In the main() method, we create a new linked list, insert four nodes, print the original list, reverse the list using the reverseList() method, and then print the reversed list.

1.3 Recursive Algorithm Implementation

Here’s an example of a recursive algorithm implementation for a singly linked list in Java:

Recursive algorithm code

public class LinkedList {
    Node head;

    static class Node {
        int data;
        Node next;

        Node(int d) {
            data = d;
            next = null;
        }
    }

    // Method to reverse the linked list recursively
    public Node reverseList(Node current) {
        if (current == null || current.next == null) {
            return current;
        }
        Node newHead = reverseList(current.next);
        current.next.next = current;
        current.next = null;
        return newHead;
    }

    // Method to insert a new node at the beginning of the linked list
    public void insert(int newData) {
        Node newNode = new Node(newData);
        newNode.next = head;
        head = newNode;
    }

    // Method to print the linked list
    public void printList() {
        Node node = head;
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
    }

    // Main method to test the implementation
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.insert(1);
        list.insert(2);
        list.insert(3);
        list.insert(4);

        System.out.println("Original List:");
        list.printList();

        list.head = list.reverseList(list.head);

        System.out.println("\nReversed List:");
        list.printList();
    }
}

In this implementation, the reverseList() method is a recursive method that reverses the linked list by calling itself repeatedly on the remaining nodes after the current node. At each recursive call, the method returns the new head of the reversed list. The base case for the recursion is when the current node is null or the last node in the list. To reverse the linked list, the method first calls itself on the next node, then sets the next pointer of the next node to point back to the current node, and sets the next pointer of the current node to null. Finally, the method returns the new head of the reversed list. The insert() method is used to add new nodes to the beginning of the linked list, and the printList() method is used to print the list. In the main() method, we create a new linked list, insert four nodes, print the original list, and reverse the list using the reverseList() method, and then print the reversed list.

This concludes our tutorial, and I trust that the article provided you with the information you sought. I wish you happy learning and encourage you to share your newfound knowledge with others!

2. Conclusion

Iterative and recursive algorithms are both used to reverse a linked list in Java. The iterative algorithm iterates through the linked list, reversing the next pointers of each node to point to the previous node instead of the next node. This is done using three pointers: prev, current, and next. At each iteration, current.next is set to prev, and then prev, current, and next are updated to move to the next nodes in the list. On the other hand, the recursive algorithm reverses the linked list by calling itself repeatedly on the remaining nodes after the current node. At each recursive call, the method returns the new head of the reversed list. The base case for the recursion is when the current node is null or the last node in the list.

Both algorithms have their advantages and disadvantages. The iterative algorithm is generally more efficient in terms of time and space complexity, whereas the recursive algorithm is often more concise and easier to understand. It is important to choose the appropriate algorithm depending on the specific requirements and constraints of the problem at hand. You can download the source code from the Downloads section.

3. Download the Project

This tutorial aimed to provide an understanding of reversing a linked list in java and demonstrate how to implement it.

Download
You can download the full source code of this example here: Reverse a linked list

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button