Print a list in reverse order in C++
Lists are sequence containers that are implemented as a doubly linked list and allow iteration in both directions. This post will discuss how to print a list in reverse order in C++.
1. Using std::copy function
An elegant solution is to use std::copy to copy the list’s contents to the output stream (in this case std::cout) with the help of the output iterator std::ostream_iterator.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <list> #include <algorithm> #include <iterator> void print(std::list<char> const &list) { std::copy(list.rbegin(), list.rend(), std::ostream_iterator<char>(std::cout, " ")); } int main() { std::list<char> list = { 'x', 'y', 'z' }; print(list); return 0; } |
Output:
z y x
Starting C++17, we can use std::experimental::ostream_joiner defined in header <experimental/iterator>. It is a single-pass output iterator which can write successive objects into the std::cout, using the << operator, separated by a delimiter between every two objects.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> #include <list> #include <experimental/iterator> void print(std::list<char> const &list) { std::copy(list.rbegin(), list.rend(), std::experimental::make_ostream_joiner(std::cout, " ")); } int main() { std::list<char> list = { 'x', 'y', 'z' }; print(list); return 0; } |
Output:
z y x
2. Using std::for_each function
We can also use the std::for_each algorithm that accepts an input range defined by two iterators and applies a specified function on each element in that range. The specified function may be a unary function, or an object of a class overloading the () operator or a lambda expression.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <iostream> #include <list> #include <algorithm> void print(const int &i) { std::cout << i << ' '; } struct myclass { void operator() (int i) { std::cout << i << ' '; } } ob; void print_list(std::list<char> const &list) { // specify a lambda expression std::for_each(list.rbegin(), list.rend(), [](const auto &e) { std::cout << e << " "; }); // or specify a function // std::for_each(list.rbegin(), list.rend(), print); // or pass an object of a class overloading the ()operator // std::for_each(list.rbegin(), list.rend(), ob); } int main() { std::list<char> list = { 'x', 'y', 'z' }; print_list(list); return 0; } |
Output:
z y x
3. Using Iterators
We can also use the iterators to print a list. Since we’re not modifying the contents of the list inside the while loop, consider using the const_iterator, which is returned by cbegin() and cend(). Before C++11, we can use begin() and end().
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <list> void print(std::list<char> const &list) { for (auto it = list.crbegin(); it != list.crend(); it++) { std::cout << *it << ' '; } } int main() { std::list<char> list = { 'x', 'y', 'z' }; print(list); return 0; } |
Output:
z y x
4. Overloading << Operator
The output streams (such as cout) use the insertion (<<) operator, which can be overloaded to accept a list object. We basically need to overload the << operator to recognize an ostream object on the left and a list object on the right.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <iostream> #include <list> std::ostream &operator<<(std::ostream &os, const std::list<char> &list) { for (auto it = list.crbegin(); it != list.crend(); it++) { std::cout << *it << ' '; } return os; } int main() { std::list<char> list = { 'x', 'y', 'z' }; std::cout << list; return 0; } |
Output:
z y x
That's all about printing a list in reverse order in C++.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)