How to Print Linked List in C++

Jinku Hu Feb 12, 2024
  1. Use a Loop to Print All Elements in the Linked List in C++
  2. Use Recursion to Print All Elements in the Linked List in C++
  3. Use STL Algorithms to Print All Elements in the Linked List in C++
  4. Use a Range-Based for Loop to Print All Elements in the Linked List in C++
  5. Conclusion
How to Print Linked List in C++

Working with linked lists is a fundamental aspect of data structures in programming. Printing the contents of a linked list is a common operation, and in C++, there are multiple approaches to achieve this.

In this article, we’ll explore various methods, including traditional loops, recursion, STL algorithms, and the modern range-based for loop.

Use a Loop to Print All Elements in the Linked List in C++

In C++, one common method to print the elements of a linked list is by using a loop. To do this, we will iterate through each node and print its data until we reach the end of the list.

We can use a loop construct, such as a while or for loop, to traverse the list. The loop continues until we encounter a null reference, indicating the end of the list.

For the sake of illustration, we’ll use a simple singly linked list with elements representing cities, countries, and keys.

Code Example:

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

using namespace std;

struct Node {
  Node* next;
  string city;
  string country;
  int key;
};

void printLinkedList(Node* head) {
  Node* current = head;
  while (current != nullptr) {
    cout << "key: " << current->key << endl
         << "city: " << current->city << endl
         << "country: " << current->country << endl
         << endl;
    current = current->next;
  }
}

int main() {
  Node* root = nullptr;
  Node* tmp = nullptr;

  vector<pair<string, string>> list = {{"Tokyo", "Japan"},
                                       {"New York", "United States"},
                                       {"Mexico City", "Mexico"},
                                       {"Tangshan", "China"},
                                       {"Tainan", "Taiwan"}};

  root = new Node;
  tmp = root;

  for (int i = 0; i < list.size(); ++i) {
    tmp->next = new Node;
    tmp->next->key = i + 1;
    tmp->next->city = list[i].first;
    tmp->next->country = list[i].second;
    tmp = tmp->next;
  }

  printLinkedList(root->next);

  Node* current = root;
  while (current != nullptr) {
    Node* temp = current;
    current = current->next;
    delete temp;
  }

  return EXIT_SUCCESS;
}

Here, the code begins by defining a Node structure representing each element of the linked list. The structure includes a pointer to the next node and three data members: city, country, and key.

struct Node {
  Node* next;
  string city;
  string country;
  int key;
};

Next, a function named printLinkedList is defined to print the linked list’s elements. It takes the head of the list as a parameter and utilizes a while loop to iterate through each node.

Inside the loop, it outputs the key, city, and country of the current node to the console.

void printLinkedList(Node* head) {
  Node* current = head;
  while (current != nullptr) {
    cout << "key: " << current->key << endl
         << "city: " << current->city << endl
         << "country: " << current->country << endl
         << endl;
    current = current->next;
  }
}

In the main function, a linked list is constructed using a vector of city-country pairs. The program initializes a root pointer and a temporary pointer tmp to manage the creation of nodes.

A for loop iterates through the vector, creating new nodes for each pair and linking them together to form the linked list.

int main() {
  Node* root = nullptr;
  Node* tmp = nullptr;

  vector<pair<string, string>> list = {{"Tokyo", "Japan"},
                                       {"New York", "United States"},
                                       {"Mexico City", "Mexico"},
                                       {"Tangshan", "China"},
                                       {"Tainan", "Taiwan"}};

  root = new Node;
  tmp = root;

  for (int i = 0; i < list.size(); ++i) {
    tmp->next = new Node;
    tmp->next->key = i + 1;
    tmp->next->city = list[i].first;
    tmp->next->country = list[i].second;
    tmp = tmp->next;
  }
}

The linked list is then printed using the printLinkedList function, starting from the second node (root->next) since the first node (root) is a dummy node created for initialization purposes.

printLinkedList(root->next);

Finally, the program deallocates the memory allocated for the linked list to prevent memory leaks. It does so by iterating through the list with a while loop, freeing each node’s memory and updating the current pointer accordingly.

Node* current = root;
while (current != nullptr) {
  Node* temp = current;
  current = current->next;
  delete temp;
}

return EXIT_SUCCESS;
}

Output:

key: 1
city: Tokyo
country: Japan

key: 2
city: New York
country: United States

key: 3
city: Mexico City
country: Mexico

key: 4
city: Tangshan
country: China

key: 5
city: Tainan
country: Taiwan

This output demonstrates the successful printing of the linked list elements using a loop, showcasing the key, city, and country information for each node.

Use Recursion to Print All Elements in the Linked List in C++

Recursion is a powerful technique in programming that involves a function calling itself. When dealing with data structures like linked lists, recursion can also be an elegant and efficient way to traverse and process the elements.

To print all elements in a linked list using recursion, we can define a recursive function that prints the current node’s data and then calls itself with the next node. The base case for the recursion is when we reach the end of the list, which is indicated by a null reference.

Code Example:

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

using namespace std;

struct Node {
  Node* next;
  string city;
  string country;
  int key;
};

void printLinkedListRecursive(Node* current) {
  if (current == nullptr) {
    cout << endl;
    return;
  }

  cout << "key: " << current->key << endl
       << "city: " << current->city << endl
       << "country: " << current->country << endl
       << endl;

  printLinkedListRecursive(current->next);
}

int main() {
  Node* root = nullptr;
  Node* tmp = nullptr;

  vector<pair<string, string>> list = {{"Tokyo", "Japan"},
                                       {"New York", "United States"},
                                       {"Mexico City", "Mexico"},
                                       {"Tangshan", "China"},
                                       {"Tainan", "Taiwan"}};

  root = new Node;
  tmp = root;

  for (int i = 0; i < list.size(); ++i) {
    tmp->next = new Node;
    tmp->next->key = i + 1;
    tmp->next->city = list[i].first;
    tmp->next->country = list[i].second;
    tmp = tmp->next;
  }

  printLinkedListRecursive(root->next);

  Node* current = root;
  while (current != nullptr) {
    Node* temp = current;
    current = current->next;
    delete temp;
  }

  return EXIT_SUCCESS;
}

The code introduces a new function, printLinkedListRecursive, to print the linked list using recursion. This function takes a Node* as an argument and serves as the recursive function responsible for printing each node’s data.

Inside the function, a base case is defined: if the current node is nullptr, indicating the end of the list, the function prints a new line and returns, terminating the recursion. Otherwise, the data of the current node is printed, and the function is recursively called for the next node.

void printLinkedListRecursive(Node* current) {
  if (current == nullptr) {
    cout << endl;
    return;
  }

  cout << "key: " << current->key << endl
       << "city: " << current->city << endl
       << "country: " << current->country << endl
       << endl;

  printLinkedListRecursive(current->next);
}

In the main function, a linked list is constructed similarly to the previous example. After initializing the list, the printLinkedListRecursive function is invoked with the second node (root->next) as its argument, initiating the recursive printing process.

int main() {
  Node* root = nullptr;
  Node* tmp = nullptr;

  vector<pair<string, string>> list = {{"Tokyo", "Japan"},
                                       {"New York", "United States"},
                                       {"Mexico City", "Mexico"},
                                       {"Tangshan", "China"},
                                       {"Tainan", "Taiwan"}};

  root = new Node;
  tmp = root;

  for (int i = 0; i < list.size(); ++i) {
    tmp->next = new Node;
    tmp->next->key = i + 1;
    tmp->next->city = list[i].first;
    tmp->next->country = list[i].second;
    tmp = tmp->next;
  }

  printLinkedListRecursive(root->next);
}

The program then deallocates the memory allocated for the linked list to prevent memory leaks, as explained in the previous example.

Output:

key: 1
city: Tokyo
country: Japan

key: 2
city: New York
country: United States

key: 3
city: Mexico City
country: Mexico

key: 4
city: Tangshan
country: China

key: 5
city: Tainan
country: Taiwan

This output shows the successful printing of the linked list elements using recursion, producing the same key, city, and country information for each node as in the previous example.

Use STL Algorithms to Print All Elements in the Linked List in C++

C++ Standard Template Library (STL) provides a rich set of algorithms that can be applied to various data structures, including linked lists.

To use STL algorithms with linked lists, we can convert the linked list into a range using iterators. Iterators act as a bridge between the data structure and the algorithms, allowing seamless integration.

Code Example:

#include <algorithm>
#include <iostream>
#include <list>

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

void printLinkedList(const std::list<Node*>& linkedList) {
  std::for_each(linkedList.begin(), linkedList.end(), [](const Node* node) {
    std::cout << "City: " << node->data << std::endl;
  });
}

int main() {
  std::list<Node*> linkedList;
  linkedList.push_back(new Node{"Tokyo", nullptr});
  linkedList.push_back(new Node{"New York", nullptr});
  linkedList.push_back(new Node{"Mexico City", nullptr});
  linkedList.push_back(new Node{"Tangshan", nullptr});
  linkedList.push_back(new Node{"Tainan", nullptr});

  printLinkedList(linkedList);

  std::for_each(linkedList.begin(), linkedList.end(),
                [](Node* node) { delete node; });

  return EXIT_SUCCESS;
}

In this code example, a linked list is represented using the std::list container from the Standard Template Library. The Node structure defines each element of the linked list, containing a string data and a pointer to the next node (next).

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

The printLinkedList function takes a std::list<Node*> as an argument and uses the std::for_each algorithm to iterate over each node in the linked list. The lambda function within std::for_each prints the data of each node to the console.

void printLinkedList(const std::list<Node*>& linkedList) {
  std::for_each(linkedList.begin(), linkedList.end(), [](const Node* node) {
    std::cout << "City: " << node->data << std::endl;
  });
}

In the main function, a linked list is constructed using the std::list container, and nodes are added using the push_back method. The linked list is then printed using the printLinkedList function, which internally uses the std::for_each algorithm.

int main() {
  std::list<Node*> linkedList;
  linkedList.push_back(new Node{"Tokyo", nullptr});
  linkedList.push_back(new Node{"New York", nullptr});
  linkedList.push_back(new Node{"Mexico City", nullptr});
  linkedList.push_back(new Node{"Tangshan", nullptr});
  linkedList.push_back(new Node{"Tainan", nullptr});

  printLinkedList(linkedList);

The std::for_each algorithm is used again in the main function to deallocate memory, iterating over the linked list and deleting each node.

std::for_each(linkedList.begin(), linkedList.end(),
              [](Node* node) { delete node; });

return EXIT_SUCCESS;
}

As you can see, the output shows the data of each node in the linked list, demonstrating the use of STL algorithms for printing linked lists in C++.

Output:

City: Tokyo
City: New York
City: Mexico City
City: Tangshan
City: Tainan

Use a Range-Based for Loop to Print All Elements in the Linked List in C++

C++ introduced the range-based for loop in C++11, providing a concise and readable syntax for iterating over elements in a container or sequence.

The range-based for loop simplifies the iteration process, eliminating the need for explicit iterators or loop control variables. It enhances code readability and reduces the chance of off-by-one errors.

To use a range-based for loop with a linked list, we can define a custom range using iterators or utilize a container that supports the range-based for loop directly.

Code Example:

#include <iostream>
#include <list>

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

void printLinkedList(const std::list<Node*>& linkedList) {
  for (const auto* node : linkedList) {
    std::cout << "Data: " << node->data << std::endl;
  }
}

int main() {
  std::list<Node*> linkedList = {
      new Node{"Tokyo", nullptr}, new Node{"New York", nullptr},
      new Node{"Mexico City", nullptr}, new Node{"Tangshan", nullptr},
      new Node{"Tainan", nullptr}};

  printLinkedList(linkedList);

  for (const auto* node : linkedList) {
    delete node;
  }

  return EXIT_SUCCESS;
}

The code example employs the range-based for loop to iterate over a linked list represented by the std::list container. The Node structure defines each element of the linked list, containing a string data and a pointer to the next node (next).

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

The printLinkedList function takes a std::list<Node*> as an argument and utilizes the range-based for loop to iterate over each node in the linked list. Inside the loop, it prints the data of each node to the console.

void printLinkedList(const std::list<Node*>& linkedList) {
  for (const auto* node : linkedList) {
    std::cout << "Data: " << node->data << std::endl;
  }
}

In the main function, the linked list is constructed using the std::list container, and nodes are added using the initializer list. The linked list is then printed using the printLinkedList function, which internally uses the range-based for loop.

int main() {
  std::list<Node*> linkedList = {
      new Node{"Tokyo", nullptr}, new Node{"New York", nullptr},
      new Node{"Mexico City", nullptr}, new Node{"Tangshan", nullptr},
      new Node{"Tainan", nullptr}};

  printLinkedList(linkedList);

Another range-based for loop is used in the main function to deallocate memory, iterating over the linked list and deleting each node.

for (const auto* node : linkedList) {
  delete node;
}

return EXIT_SUCCESS;
}

The program concludes by returning EXIT_SUCCESS, which indicates successful execution. The output of the program illustrates the data of each node in the linked list, demonstrating the simplicity and readability provided by the range-based for loop in C++.

Output:

Data: Tokyo
Data: New York
Data: Mexico City
Data: Tangshan
Data: Tainan

Conclusion

In this article, we’ve covered multiple methods for printing a linked list in C++. Each approach has its advantages, and the choice depends on factors such as code readability, efficiency, and personal preference.

Whether you opt for traditional loops, recursion, STL algorithms, or the modern range-based for loop, understanding these techniques empowers you to handle linked list operations effectively in your C++ programs.

Remember to adapt the provided code snippets based on your specific use case and coding style. Experimenting with different methods will deepen your understanding of linked list manipulation in C++.

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++ List