How to Reverse the Linked List in C++

Jinku Hu Feb 02, 2024
How to Reverse the Linked List in C++

This article will demonstrate how to reverse a linked list data structure in C++.

Use Iterative Function to Reverse the Linked List in C++

We assume that the target object is a singly linked list and implement code snippets accordingly. At first, we need to look at the basic function utilities in the driver code implemented to demonstrate the example.

The linked list node is a simple struct with a single string data object and a pointer to the next node. We also have the addNewNode function that takes two arguments, Node* and a reference to the string. The addNewNode function is invoked multiple times in the main routine to construct a new list object and store strings from the data_set vector. The function allocates each node on dynamic memory and returns the pointer to the newly created node.

Another useful function for our linked list data structure is printNodes, which is used to output data from every node to the cout stream. The latter one will help us loosely verify the correctness of the reversal function. Note that printNodes keeps the count of nodes during the list traversal and prints the index for each element. Finally, we need to deallocate all nodes before the program exits. This step is not necessary for reversal function demonstration, but it’s important for any real-world project to clean up all the memory allocated during run-time.

#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

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

struct Node *addNewNode(struct Node *node, string &data) {
  auto new_node = new Node;
  if (node) node->next = new_node;
  new_node->next = nullptr;
  new_node->data = data;
  return new_node;
}

void freeNodes(struct Node *node) {
  struct Node *tmp = nullptr;
  while (node) {
    tmp = node;
    node = node->next;
    delete tmp;
  }
}

void printNodes(struct Node *node) {
  auto count = 0;
  while (node) {
    cout << "node " << count << " - data: " << node->data << endl;
    node = node->next;
    count++;
  }
}

int main() {
  struct Node *tmp, *head = nullptr;

  vector<string> data_set = {"Rocket Lake", "Alder Lake", "Tiger Lake",
                             "Meteor Lake"};

  head = addNewNode(head, data_set.at(0));
  tmp = head;
  for (auto it = data_set.begin() + 1; it != data_set.end(); ++it) {
    tmp = addNewNode(tmp, *it);
  }

  printNodes(head);

  freeNodes(head);
  return EXIT_SUCCESS;
}

Output:

node 0 - data: Rocket Lake
node 1 - data: Alder Lake
node 2 - data: Tiger Lake
node 3 - data: Meteor Lake

Once we initialize a new linked list and store the head of the list in a separate pointer, we can use it to reverse the contents. In this case, we implemented the reverseList function, which accepts a single Node* argument and returns a new root node. At first, we duplicate the passed pointer and store it as a head variable. We also need two additional Node type pointers to do internal book-keeping during the while loop.

The reversal algorithm can be described as follows: We store the next node pointer in a temporary variable (next) and assign the nullptr value to the original one. As a result, the original head node will be pointing to the nullptr as its next node in the list. Next, we update the head variable to store the next (the second) node in the original list and also save the address of the original head node in a separate temporary variable.

We repeat the previous steps until the head pointer evaluates to nullptr, which would mean that the end of the list is reached. In the end, we return the address of the new head node stored in n temporary variable. Consequently, the main program calls the printNodes function for the user to compare modified linked list contents.

#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

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

struct Node *addNewNode(struct Node *node, string &data) {
  auto new_node = new Node;
  if (node) node->next = new_node;
  new_node->next = nullptr;
  new_node->data = data;
  return new_node;
}

void freeNodes(struct Node *node) {
  struct Node *tmp = nullptr;
  while (node) {
    tmp = node;
    node = node->next;
    delete tmp;
  }
}

void printNodes(struct Node *node) {
  auto count = 0;
  while (node) {
    cout << "node " << count << " - data: " << node->data << endl;
    node = node->next;
    count++;
  }
}

Node *reverseList(struct Node *node) {
  auto head = node;
  Node *n = nullptr;
  Node *next = nullptr;

  while (head) {
    next = head->next;
    head->next = n;

    n = head;
    head = next;
  }
  return n;
}

int main() {
  struct Node *tmp, *head = nullptr;

  vector<string> data_set = {"Rocket Lake", "Alder Lake", "Tiger Lake",
                             "Meteor Lake"};

  head = addNewNode(head, data_set.at(0));
  tmp = head;
  for (auto it = data_set.begin() + 1; it != data_set.end(); ++it) {
    tmp = addNewNode(tmp, *it);
  }

  printNodes(head);

  cout << " ----------------------------------- " << endl;
  printNodes(reverseList(head));

  freeNodes(head);
  return EXIT_SUCCESS;
}

Output:

node 0 - data: Rocket Lake
node 1 - data: Alder Lake
node 2 - data: Tiger Lake
node 3 - data: Meteor Lake
 -----------------------------------
node 0 - data: Meteor Lake
node 1 - data: Tiger Lake
node 2 - data: Alder Lake
node 3 - data: Rocket Lake
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ Data Structure