Tutorials Logic, IN info@tutorialslogic.com

C++ Standard Library Containers and Algorithms

Containers Express Access Patterns

The C++ standard library separates storage structures from algorithms through iterators and ranges. Container choice should follow required lookup, ordering, insertion, traversal, memory locality, and iterator-stability behavior rather than habit.

A vector is the default sequence for many workloads because contiguous storage supports fast traversal and random access. Ordered associative containers maintain sorted keys; unordered containers use hashing; adapters such as stack and queue expose restricted operations over another container.

Choose A Container And Use Algorithms

The Standard Template Library provides containers, iterators, algorithms, function objects, and utilities. Start with std::vector for a dynamic sequence, std::map for ordered key-value lookup, std::unordered_map for average constant-time hashing, std::set for unique ordered values, and std::queue for first-in-first-out processing.

Use range-based loops for simple traversal and iterators when algorithms or positions are required. Algorithms such as sort, find_if, count_if, transform, and accumulate separate operation from storage. Include the correct headers and prefer algorithms over handwritten loops when they express the intent clearly.

Understand invalidation. Growing a vector may invalidate pointers, references, and iterators; erasing from containers has container-specific rules. Check whether lookup succeeded before dereferencing an iterator. Use const_iterator or const references when code should not modify elements.

  • Use vector as the default sequence container.
  • Choose ordered or hashed maps from requirements.
  • Express operations with standard algorithms.
  • Check end() before dereferencing lookup results.
  • Learn iterator invalidation for each container used.

Complexity, Allocation, Ranges, And Custom Types

Container choice affects memory layout and cache behavior as well as Big-O notation. vector offers contiguous storage and often outperforms node-based containers even when insertion complexity appears worse. Reserve capacity when size is predictable, but do not retain excessive memory without need.

Custom keys need ordering or hashing consistent with equality. Avoid modifying keys inside associative containers. Use emplace only when it actually constructs in place and improves clarity. Prefer transparent comparators for heterogeneous lookup where useful, and measure unordered container behavior under realistic hash distribution.

Modern C++ ranges and views compose filtering and transformation lazily. Be careful with view lifetime when the source is temporary or destroyed. Use execution policies only after confirming thread safety and benefit. Profile allocations, branch behavior, and data locality before replacing clear STL code with custom structures.

  • Consider cache locality alongside asymptotic complexity.
  • Reserve vector capacity from known size.
  • Keep hashing and equality consistent.
  • Use ranges without creating dangling views.
  • Profile before replacing standard containers or algorithms.

Compare Library Choices

The examples pair operations with containers and make iterator, comparator, and complexity assumptions explicit.

Vector algorithms for a score report

Algorithms keep filtering, sorting, and aggregation explicit.

Vector algorithms for a score report
std::vector<int> scores{72, 91, 65, 88, 91};

std::sort(scores.begin(), scores.end(), std::greater<>{});
scores.erase(std::unique(scores.begin(), scores.end()), scores.end());

const int total = std::accumulate(scores.begin(), scores.end(), 0);
const auto passing = std::count_if(scores.begin(), scores.end(),
    [](int score) { return score >= 70; });
  • unique removes adjacent duplicates after sorting.
  • Use a wider accumulator type when overflow is possible.
  • Algorithms work through iterator ranges.

Word frequency with unordered_map

Hash lookup provides a simple counting table.

Word frequency with unordered_map
std::unordered_map<std::string, std::size_t> frequency;
for (const std::string& word : words) {
    ++frequency[word];
}

std::vector<std::pair<std::string, std::size_t>> ranked(
    frequency.begin(), frequency.end());

std::sort(ranked.begin(), ranked.end(),
    [](const auto& a, const auto& b) {
        return a.second > b.second;
    });
  • unordered_map does not preserve sorted order.
  • Copy into a vector when ranked output is required.
  • Normalize words before counting if case should be ignored.
Before you move on

Library Choice Review

5 checks
  • List required operations before choosing a container.
  • Prefer standard algorithms over handwritten traversal when intent becomes clearer.
  • Know which mutations invalidate iterators and references.
  • Provide matching equality and hashing for unordered custom keys.
  • Measure before replacing contiguous storage with node-based containers.

Library Questions

A reallocation invalidates all iterators, pointers, and references. Erasing also invalidates positions at and after the erased element.

Use map for sorted keys and predictable logarithmic operations. Use unordered_map when hash lookup is suitable and ordering is irrelevant.

An algorithm states the intent clearly and has well-defined iterator and complexity requirements.

Next Step
Next Practice

Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.