std::list


C++ STL Linked List Examples

The C++ Standard Template Library (STL) provides robust implementations of linked lists through std::list and std::forward_list. These container classes offer efficient insertion and deletion operations along with a wide range of member functions for list manipulation.

Key Characteristics

Example 1: Basic Usage of std::list

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

int main() {
    std::list<int> myList = {3, 1, 4, 1, 5, 9};

    // Insert at the beginning and end
    myList.push_front(0);
    myList.push_back(2);

    // Display the list
    std::cout << "List contents: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Sort the list
    myList.sort();

    // Remove duplicates
    myList.unique();

    // Display the sorted list without duplicates
    std::cout << "Sorted list without duplicates: ";
    for (const auto& elem : myList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation

Example 2: std::forward_list for Memory-Efficient Operations

#include <iostream>
#include <forward_list>
#include <algorithm>

int main() {
    std::forward_list<int> myForwardList = {3, 1, 4, 1, 5, 9};

    // Insert at the beginning
    myForwardList.push_front(0);

    // Insert after a specific position
    auto it = myForwardList.begin();
    std::advance(it, 2);
    myForwardList.insert_after(it, 2);

    // Display the list
    std::cout << "Forward list contents: ";
    for (const auto& elem : myForwardList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // Remove all elements with a specific value
    myForwardList.remove(1);

    // Reverse the list
    myForwardList.reverse();

    // Display the modified list
    std::cout << "Modified forward list: ";
    for (const auto& elem : myForwardList) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation

Example 3: Using std::list with Custom Objects

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

class Person {
public:
    std::string name;
    int age;

    Person(const std::string& n, int a) : name(n), age(a) {}

    // For sorting based on age
    bool operator<(const Person& other) const {
        return age < other.age;
    }
};

// For displaying Person objects
std::ostream& operator<<(std::ostream& os, const Person& p) {
    return os << p.name << " (" << p.age << ")";
}

int main() {
    std::list<Person> people = {
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35},
        {"David", 28}
    };

    // Display original list
    std::cout << "Original list:" << std::endl;
    for (const auto& person : people) {
        std::cout << person << std::endl;
    }

    // Sort the list based on age
    people.sort();

    // Display sorted list
    std::cout << "\nSorted list by age:" << std::endl;
    for (const auto& person : people) {
        std::cout << person << std::endl;
    }

    // Find a person by name
    auto it = std::find_if(people.begin(), people.end(),
                           [](const Person& p) { return p.name == "Charlie"; });
    if (it != people.end()) {
        std::cout << "\nFound: " << *it << std::endl;
    }

    return 0;
}

Explanation

Additional Considerations

  1. Performance: While std::list and std::forward_list provide O(1) insertion and deletion, they may have worse cache performance compared to contiguous containers like std::vector for traversal operations.

  2. Memory Allocation: These containers allocate memory for each node separately, which can lead to memory fragmentation in some scenarios.

  3. Iterator Invalidation: Iterators to std::list and std::forward_list remain valid after insertion or removal operations, except for the erased elements.

  4. Use Cases: These containers are particularly useful when frequent insertion and deletion operations are required at arbitrary positions in the sequence.

  5. Algorithms: Many STL algorithms work efficiently with these containers, but some (like std::sort) are not applicable to std::forward_list due to its unidirectional nature.

Summary

The STL provides powerful and flexible implementations of linked lists through std::list and std::forward_list. These containers offer efficient insertion and deletion operations, along with a rich set of member functions and compatibility with STL algorithms.

std::list is a doubly linked list that allows bidirectional traversal and provides operations like push_back(), which are not available in std::forward_list. It's more versatile but uses more memory per node.

std::forward_list is a singly linked list, offering a more memory-efficient solution when only forward traversal is needed. It's particularly useful in scenarios where memory usage is a critical factor.

Both containers are excellent choices when the primary operations involve frequent insertions and deletions at arbitrary positions in the sequence. They provide a balance of functionality and performance, making them suitable for a wide range of applications in C++ programming.

Previous Page | Course Schedule | Course Content