---
# System prepended metadata

title: 'Collections: C++'

---

# Collections: C++
## Vector
A vector in C++ is a dynamic array that allows efficient insertion and removal of elements at the end. It provides random access to elements.
```cpp!
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
    // Declaration and Initialization
    std::vector<int> vec = {1, 2, 3};

    // Adding Elements to End
    vec.push_back(4);

    // Accessing Elements
    std::cout << "First Element: " << vec[0] << std::endl;

    // Updating Elements
    vec[1] = 22;

    // Removing Elements From End
    vec.pop_back();

    // Checking if an Element Exists
    bool containsElement = std::find(vec.begin(), vec.end(), 2) != vec.end();
    std::cout << "Contains Element 2: " << containsElement << std::endl;

    // Getting the Size
    std::cout << "Size of Vector: " << vec.size() << std::endl;

    // Iterating Through Elements
    for (int element : vec) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // Checking if the Vector is Empty
    bool isEmpty = vec.empty();
    std::cout << "Is Vector Empty: " << isEmpty << std::endl;

    // Clearing All Elements
    vec.clear();
    std::cout << "Vector after clearing: ";
    for (int element : vec) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Stack
A stack in C++ is a Last In First Out (LIFO) data structure. Elements are added (pushed) and removed (popped) from the top.
```cpp!
#include <iostream>
#include <stack>

int main() {
    // Declaration
    std::stack<int> stack;

    // Pushing Elements
    stack.push(1);
    stack.push(2);
    stack.push(3);

    // Accessing the Top Element
    std::cout << "Top Element: " << stack.top() << std::endl;

    // Popping Elements
    stack.pop();

    // Checking if the Stack is Empty
    bool isEmpty = stack.empty();
    std::cout << "Is Stack Empty: " << isEmpty << std::endl;

    return 0;
}
```

## List
A list in C++ is a doubly-linked list that allows efficient insertion and removal of elements at both ends. It does not provide random access.
```cpp!
#include <algorithm>
#include <iostream>
#include <list>

int main() {
    // Declaration and Initialization
    std::list<int> linkedList = {1, 2, 3};

    // Adding Elements
    linkedList.push_back(4);
    linkedList.push_front(0);

    // Accessing Elements
    std::cout << "First Element: " << linkedList.front() << std::endl;

    // Updating Elements
    auto it = std::find(linkedList.begin(), linkedList.end(), 2);
    if (it != linkedList.end()) {
        *it = 22;
    }

    // Removing Elements
    linkedList.pop_back();
    linkedList.pop_front();

    // Checking if an Element Exists
    bool containsElement = std::find(linkedList.begin(), linkedList.end(), 2) != linkedList.end();
    std::cout << "Contains Element 2: " << containsElement << std::endl;

    // Getting the Size
    std::cout << "Size of List: " << linkedList.size() << std::endl;

    // Iterating Through Elements
    for (int element : linkedList) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // Checking if the List is Empty
    bool isEmpty = linkedList.empty();
    std::cout << "Is List Empty: " << isEmpty << std::endl;

    // Clearing All Elements
    linkedList.clear();
    std::cout << "List after clearing: ";
    for (int element : linkedList) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Unordered_set
An unordered_set in C++ is an unordered collection of unique elements. It uses a hash table to provide constant-time average complexity for common operations.
```cpp!
#include <iostream>
#include <unordered_set>

int main() {
    // Declaration and Initialization
    std::unordered_set<int> hashSet = {2, 4, 6, 8, 10};

    // Adding Elements
    hashSet.insert(12);
    hashSet.insert(14);

    // Accessing Elements
    std::cout << "HashSet: ";
    for (int element : hashSet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // Removing Elements
    hashSet.erase(6);

    // Checking if an Element Exists
    bool containsElement = hashSet.find(8) != hashSet.end();
    std::cout << "Contains Element 8: " << containsElement << std::endl;

    // Iterating Through Elements
    std::cout << "HashSet after removal: ";
    for (int element : hashSet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Set
A set in C++ is an ordered collection of unique elements. It automatically sorts elements in ascending order.
```cpp!
#include <iostream>
#include <set>

int main() {
    // Declaration and Initialization
    std::set<int> treeSet = {3, 1, 4, 1, 5, 9, 2, 6, 5};

    // Accessing Elements (Automatically Sorted)
    std::cout << "TreeSet: ";
    for (int element : treeSet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // Removing Elements
    treeSet.erase(4);

    // Checking if an Element Exists
    bool containsElement = treeSet.find(6) != treeSet.end();
    std::cout << "Contains Element 6: " << containsElement << std::endl;

    // Iterating Through Elements
    std::cout << "TreeSet after removal: ";
    for (int element : treeSet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Unordered_map
An unordered_map in C++ is an unordered collection of key-value pairs. It uses a hash table to provide constant-time average complexity for common operations.
```cpp!
#include <iostream>
#include <unordered_map>

int main() {
    // Declaration and Initialization
    std::unordered_map<std::string, int> hashMap = {{"One", 1}, {"Two", 2}, {"Three", 3}};

    // Adding Elements
    hashMap["Four"] = 4;

    // Accessing Elements
    std::cout << "HashMap: ";
    for (const auto& pair : hashMap) {
        std::cout << pair.first << ":" << pair.second << " ";
    }
    std::cout << std::endl;

    // Updating Elements
    hashMap["Two"] = 22;

    // Removing Elements
    hashMap.erase("One");

    // Checking if a Key Exists
    bool containsKey = hashMap.find("Three") != hashMap.end();
    std::cout << "Contains Key 'Three': " << containsKey << std::endl;

    // Iterating Through Elements
    std::cout << "HashMap after removal: ";
    for (const auto& pair : hashMap) {
        std::cout << pair.first << ":" << pair.second << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Map
A map in C++ is an ordered collection of key-value pairs. It automatically sorts elements based on the keys in ascending order.
```cpp!
#include <iostream>
#include <map>

int main() {
    // Declaration and Initialization
    std::map<std::string, int> linkedHashMap = {{"One", 1}, {"Two", 2}, {"Three", 3}};

    // Adding Elements
    linkedHashMap["Four"] = 4;

    // Accessing Elements
    std::cout << "LinkedHashMap: ";
    for (const auto& pair : linkedHashMap) {
        std::cout << pair.first << ":" << pair.second << " ";
    }
    std::cout << std::endl;

    // Updating Elements
    linkedHashMap["Two"] = 22;

    // Removing Elements
    linkedHashMap.erase("One");

    // Checking if a Key Exists
    bool containsKey = linkedHashMap.find("Three") != linkedHashMap.end();
    std::cout << "Contains Key 'Three': " << containsKey << std::endl;

    // Iterating Through Elements
    std::cout << "LinkedHashMap after removal: ";
    for (const auto& pair : linkedHashMap) {
        std::cout << pair.first << ":" << pair.second << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Priority_queue
A priority_queue in C++ is a container that provides constant-time complexity for accessing the highest or lowest priority element.
```cpp!
#include <iostream>
#include <queue>

int main() {
    // Declaration
    std::priority_queue<int> priorityQueue;

    // Adding Elements
    priorityQueue.push(3);
    priorityQueue.push(1);
    priorityQueue.push(4);
    priorityQueue.push(1);
    priorityQueue.push(5);

    // Printing the PriorityQueue
    std::cout << "PriorityQueue: ";
    while (!priorityQueue.empty()) {
        std::cout << priorityQueue.top() << " ";
        priorityQueue.pop();
    }
    std::cout << std::endl;

    return 0;
}
```

## Deque
A deque in C++ is a double-ended queue that allows efficient insertion and removal of elements at both ends. It provides random access to elements.
```cpp!
#include <algorithm>
#include <deque>
#include <iostream>

int main() {
    // Declaration and Initialization
    std::deque<int> deque = {1, 2, 3};

    // Adding Elements
    deque.push_back(4);
    deque.push_front(0);

    // Accessing Elements
    std::cout << "First Element: " << deque.front() << std::endl;

    // Updating Elements
    deque[1] = 22;

    // Removing Elements
    deque.pop_back();
    deque.pop_front();

    // Checking if an Element Exists
    bool containsElement = std::find(deque.begin(), deque.end(), 2) != deque.end();
    std::cout << "Contains Element 2: " << containsElement << std::endl;

    // Getting the Size
    std::cout << "Size of Deque: " << deque.size() << std::endl;

    // Iterating Through Elements
    std::cout << "Deque: ";
    for (int element : deque) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // Checking if the Deque is Empty
    bool isEmpty = deque.empty();
    std::cout << "Is Deque Empty: " << isEmpty << std::endl;

    // Clearing All Elements
    deque.clear();
    std::cout << "Deque after clearing: ";
    for (int element : deque) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}
```

## Comparables

- In C++, the term "comparable" usually refers to types that can be compared using standard comparison operators (e.g., `<`, `<=`, `==`, `!=`, `>`, `>=`). 
- For user-defined types, you can make them comparable by overloading these operators.

Here's an example of a comparable class in C++:

```cpp!
#include <iostream>

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

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

    // Overloading the < operator to make instances of Person comparable
    bool operator<(const Person& other) const {
        return age < other.age;
    }
};

int main() {
    Person person1("Alice", 28);
    Person person2("Bob", 22);

    if (person1 < person2) {
        std::cout << person1.name << " is younger than " << person2.name << std::endl;
    } else {
        std::cout << person1.name << " is not younger than " << person2.name << std::endl;
    }

    return 0;
}
```

## Comparators

- In C++, comparators are typically implemented using function objects (functors) or lambda functions.

Here's an example of using a comparator to sort a collection of `Person` objects:

```cpp!
#include <algorithm>
#include <iostream>
#include <vector>

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

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

// Functor (function object) to compare Person objects based on age
struct AgeComparator {
    bool operator()(const Person& person1, const Person& person2) const {
        return person1.age < person2.age;
    }
};

int main() {
    std::vector<Person> people = {{"Alice", 28}, {"Bob", 22}, {"Charlie", 25}};

    // Sort the vector using the AgeComparator functor
    std::sort(people.begin(), people.end(), AgeComparator());

    // Iterate the vector of people and check if it is now sorted based on age
    for (const Person& person : people) {
        std::cout << person.name << " - " << person.age << '\t';
    }
    std::cout << std::endl;

    // Sort the vector using comparator lambda
    std::sort(people.begin(), people.end(), [](const Person& A, const Person& B) {
        return A.age > B.age;
    });

    for (const Person& person : people) {
        std::cout << person.name << " - " << person.age << '\t';
    }
    std::cout << std::endl;

    return 0;
}
```