DSA Tracker

DSA Tracker

Beginner path · C++

Updated 2026-10-21

Learn DSA in C++ from scratch

C++ suits learners who want direct control over containers, references and performance, especially for competitive programming. The STL is powerful, but you must understand ownership, copying and numeric types instead of relying on the syntax alone.

What you need from C++ before DSA

01

Variables and types

Choosing int or long long changes whether a sum can overflow.

#include <iostream>
using namespace std;
int main() {
    int count = 3;
    cout << "items " << count << endl;
}

Output: items 3

02

Conditionals and loops

Array scans and graph traversals are built from branches and iteration.

#include <iostream>
using namespace std;
int main() {
    int total = 0;
    for (int value : {2, 4, 5}) if (value % 2 == 0) total += value;
    cout << total << endl;
}

Output: 6

03

Functions

Functions make an algorithm's inputs and output visible at the call site.

#include <iostream>
using namespace std;
int doubleValue(int value) { return value * 2; }
int main() { cout << doubleValue(6) << endl; }

Output: 12

04

Recursion

Recursive functions express tree traversal and divide-and-conquer directly.

#include <iostream>
using namespace std;
void countdown(int n) { if (n == 0) return; cout << n << endl; countdown(n - 1); }
int main() { countdown(3); }

Output: 3 2 1

05

Arrays and lists

vector is the resizable indexed container used for most sequence problems.

#include <iostream>
#include <vector>
using namespace std;
int main() { vector<int> numbers{3, 1, 2}; numbers.push_back(4); cout << numbers[1] << " " << numbers.size() << endl; }

Output: 1 4

06

Strings

std::string supports indexing and comparison for parsing and two-pointer problems.

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main() { string word = "level"; string copy = word; reverse(copy.begin(), copy.end()); cout << (word == copy) << endl; }

Output: 1

07

Hash maps and sets

Unordered containers provide average constant-time frequency and membership checks.

#include <iostream>
#include <unordered_set>
#include <unordered_map>
using namespace std;
int main() { unordered_set<int> seen{2, 4}; unordered_map<char, int> counts{{'a', 2}}; cout << seen.count(4) << " " << counts['a'] << endl; }

Output: 1 2

08

References and copying

A reference aliases an object; copy when a function or branch needs independent storage.

#include <iostream>
#include <vector>
using namespace std;
int main() { vector<int> first{1, 2}; vector<int> second = first; second[0] = 9; cout << first[0] << " " << second[0] << endl; }

Output: 1 9

09

Classes or structs

A struct is a compact node model for linked lists and trees.

#include <iostream>
using namespace std;
struct Node { int value; };
int main() { Node node{7}; cout << node.value << endl; }

Output: 7

10

Sorting with a custom comparator

A lambda lets you sort pairs and records by the field an algorithm needs.

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
int main() { vector<pair<char, int>> items{{'b', 2}, {'a', 1}}; sort(items.begin(), items.end(), [](auto a, auto b) { return a.second < b.second; }); cout << items[0].first << endl; }

Output: a

11

Reading input

cin reads judge input, while sync_with_stdio and tie keep standard input fast.

#include <iostream>
using namespace std;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int a, b; cin >> a >> b; cout << a + b << endl; }

Input: 2 4

Output: 6

C++ toolbox for data structures

StructureC++ typeKey operations
Dynamic arrayvectorpush_back amortized O(1); indexing O(1)
String buildingstring / ostringstreamappend with += or stream insertion
Hash mapunordered_mapget/set O(1) average
Hash setunordered_setinsert/find O(1) average
Stackstackpush/pop at the top
Queuequeuepush back, pop front
Dequedequepush/pop at both ends
Priority queuepriority_queuemax-heap by default; greater<> for min
Ordered mapmapordered get/put O(log n)
Sortingsort / stable_sortcustom comparator; sort is not stable

The order to learn DSA

Follow the SDE roadmap order. Each topic starts with two Easy problems from the curated set.

Ready to move on when you can solve both without looking at a solution.

Ready to move on when you can solve both without looking at a solution.

Ready to move on when you can solve both without looking at a solution.

C++ mistakes that cost people in DSA

Letting int overflow

C++ int can overflow for large sums and products. Use long long when the input bounds require it.

Copying containers into functions

Pass large containers by reference, commonly const vector<int>&, when the function should not copy or mutate them.

Choosing the wrong heap direction

priority_queue is a max-heap by default. Use greater<> when the algorithm needs the smallest item first.

Assuming unordered_map is ordered

unordered_map is O(1) average but has no sorted iteration order. map is ordered and costs O(log n).

Assuming std::sort is stable

std::sort is not stable. Use std::stable_sort when equal-key elements must keep their relative order.

Forgetting fast input setup

For large input, call ios::sync_with_stdio(false); cin.tie(nullptr); before reading.

DSA in C++: questions, answered

Is C++ harder for learning DSA?

It has more language details than Python, but the STL maps closely to the structures used in DSA and competitive programming. Learn one container at a time.

When should I use map instead of unordered_map?

Use map when sorted keys or O(log n) worst-case behavior matters. Use unordered_map for average constant-time lookup when order is irrelevant.

How do I make a min-heap in C++?

Use priority_queue with vector and greater, such as priority_queue<int, vector<int>, greater<int>>.