Data Structures Cheat Sheet

data-structures Last verified: 28 Jul 2026

Time & space complexity — Big-O quick reference

Data StructureAccessSearchInsertDeleteSpace
ArrayO(1)O(n)O(n)O(n)O(n)
Linked ListO(n)O(n)O(1)*O(1)*O(n)
StackO(n)O(n)O(1)O(1)O(n)
QueueO(n)O(n)O(1)O(1)O(n)
Hash TableO(1)O(1)O(1)O(1)O(n)
BST (avg)O(log n)O(log n)O(log n)O(log n)O(n)
BST (worst)O(n)O(n)O(n)O(n)O(n)
AVL / Red-BlackO(log n)O(log n)O(log n)O(log n)O(n)
HeapO(n)O(n)O(log n)O(log n)O(n)

* O(1) insert/delete at head only, for a singly linked list. Tail insert is O(1) only with a tail pointer.

Arrays

Key properties

PropertyValue
AccessO(1) — random access by index
Search (linear)O(n)
Search (binary)O(log n) — only on a sorted array
Insert at endO(1) amortized (dynamic array)
Insert at index iO(n) — shift elements right
Delete at index iO(n) — shift elements left
SpaceO(n) contiguous

Sorting algorithms

AlgorithmBestAvgWorstSpaceStable
BubbleO(n)O(n²)O(n²)O(1)Yes
SelectionO(n²)O(n²)O(n²)O(1)No
InsertionO(n)O(n²)O(n²)O(1)Yes
MergeO(n log n)O(n log n)O(n log n)O(n)Yes
QuickO(n log n)O(n log n)O(n²)O(log n)No
HeapO(n log n)O(n log n)O(n log n)O(1)No
CountingO(n+k)O(n+k)O(n+k)O(k)Yes

Stable sort = equal elements keep their original relative order. Merge and Insertion sort are stable.

Binary search — must know

int lo = 0, hi = n - 1;
while (lo <= hi) {
    int mid = lo + (hi - lo) / 2;  // avoid overflow!
    if (arr[mid] == key) return mid;
    else if (arr[mid] < key) lo = mid + 1;
    else hi = mid - 1;
}
return -1;  // not found

PYQ

Which sorting algorithm has O(n) best case and O(n²) worst case?

  • A) Merge sort
  • B) Insertion sort
  • C) Heap sort
  • D) Selection sort

Why: Insertion sort is O(n) when the array is already sorted (no swaps needed), and O(n²) worst case.

PYQ

In binary search, why use mid = lo + (hi-lo)/2 instead of (lo+hi)/2?

  • A) Faster
  • B) Avoids integer overflow
  • C) More accurate
  • D) No difference

Why: If lo and hi are both large ints, lo+hi can overflow. lo+(hi-lo)/2 is safe and mathematically equivalent.

Linked lists

Node structure

// Singly linked list node
struct Node {
    int data;
    struct Node *next;
};

// Doubly linked list node
struct DNode {
    int data;
    struct DNode *prev, *next;
};

Types comparison

TypeForwardBackwardSpace
SinglyYesNo1 ptr/node
DoublyYesYes2 ptr/node
CircularYesNo*1 ptr/node
Circular DoublyYesYes2 ptr/node

Insert at head — O(1)

struct Node* insertHead(struct Node* head, int d) {
    struct Node* n = malloc(sizeof(struct Node));
    n->data = d;
    n->next = head;
    return n;  // new head
}

Floyd’s cycle detection

// Slow & fast pointer (Tortoise & Hare)
struct Node *slow = head, *fast = head;
while (fast && fast->next) {
    slow = slow->next;
    fast = fast->next->next;
    if (slow == fast) return 1;  // cycle found
}
return 0;  // no cycle

Reverse a linked list — O(n)

struct Node *prev = NULL, *curr = head, *nxt;
while (curr) {
    nxt = curr->next;
    curr->next = prev;
    prev = curr;
    curr = nxt;
}
return prev;  // new head

Find middle of list — O(n)

// When fast reaches the end, slow is at the middle
struct Node *slow = head, *fast = head;
while (fast->next && fast->next->next) {
    slow = slow->next;
    fast = fast->next->next;
}
// slow = middle node

PYQ

Time complexity of inserting at the end of a singly linked list (no tail pointer)?

  • A) O(1)
  • B) O(log n)
  • C) O(n)
  • D) O(n²)

Why: Without a tail pointer, you must traverse the entire list to find the last node — O(n).

PYQ

In Floyd's cycle detection, when does slow == fast?

  • A) When the list is empty
  • B) When there is a cycle
  • C) At the middle
  • D) Never

Why: Fast moves 2 steps, slow moves 1. If there is a cycle, fast "laps" slow and they meet inside the cycle.

Stacks — LIFO

Stack operations

OperationDescriptionArray implLinked List impl
push(x)Add to topO(1)O(1)
pop()Remove from topO(1)O(1)
peek()View top (no remove)O(1)O(1)
isEmpty()Check if emptyO(1)O(1)

Key applications

ApplicationHow the stack is used
Balanced parenthesesPush on open, pop on close
Infix → PostfixOperator stack, precedence rules
Postfix evaluationOperand stack
Function call stackOS stores return addresses
Undo / RedoTwo stacks
DFS (iterative)Node stack
Expression parsingOperator + operand stacks

Array-based stack in C

#define MAX 100
int stack[MAX], top = -1;

void push(int x) {
    if (top == MAX - 1) { printf("Overflow"); return; }
    stack[++top] = x;
}

int pop() {
    if (top == -1) { printf("Underflow"); return -1; }
    return stack[top--];
}

int peek() { return stack[top]; }

Infix → Postfix rules

Precedence: ^ > * / > + -
1. Operand           → send to output directly
2. (                 → push
3. )                 → pop until (
4. Operator          → pop while stack top has higher/equal precedence, then push
5. End of expression  → pop all remaining operators

Example: A+B*C   → ABC*+
Example: A*(B+C) → ABC+*

PYQ

What is the postfix form of the expression: (A+B)*(C-D)?

  • A) AB+CD-*
  • B) AB+*CD
  • C) A+B*C-D
  • D) ABCD+-*

Why: Evaluate inner brackets first: (A+B)→AB+, (C-D)→CD-, then multiply: AB+CD-*

PYQ

Evaluate postfix: 5 3 2 * + = ?

  • A) 16
  • B) 11
  • C) 25
  • D) 30

Why: Read left to right: push 5, push 3, push 2. * → pop 3,2 → 6, push 6. + → pop 5,6 → 11.

Queues — FIFO

Queue operations

OperationDescriptionComplexity
enqueue(x)Add to rearO(1)
dequeue()Remove from frontO(1)
front()View front elementO(1)
rear()View rear elementO(1)
isEmpty()Check emptyO(1)

Types of queues

TypeDescription
Simple QueueFIFO, linear array
Circular QueueRear wraps around — no wasted space
DequeInsert/delete at both ends (double-ended)
Priority QueueHighest priority dequeued first
Input-restricted DequeInsert only at rear, delete at both ends
Output-restricted DequeInsert at both ends, delete only at front

Circular queue (fixes wasted space)

#define MAX 5
int q[MAX], front = -1, rear = -1;

void enqueue(int x) {
    if ((rear + 1) % MAX == front) { printf("Full"); return; }
    if (front == -1) front = 0;
    rear = (rear + 1) % MAX;
    q[rear] = x;
}

int dequeue() {
    if (front == -1) return -1;  // empty
    int x = q[front];
    if (front == rear) front = rear = -1;
    else front = (front + 1) % MAX;
    return x;
}

Applications

ApplicationQueue type
BFS traversalSimple queue
OS schedulingPriority queue
Print spoolerSimple queue
Sliding window maxDeque
Cache (LRU)Deque / linked list

PYQ

In a circular queue of size 5, if front=2 and rear=4, how many elements are present?

  • A) 2
  • B) 3
  • C) 4
  • D) 5

Why: Elements = (rear − front + 1) = 4 − 2 + 1 = 3. Elements sit at positions 2, 3, 4.

Trees — binary trees & BST

Key tree terminology

TermDefinition
HeightLongest path from root to leaf
Depth of nodeDistance from the root
DegreeNumber of children
Full Binary TreeEvery node has 0 or 2 children
Complete Binary TreeAll levels full except last (left-filled)
Perfect Binary TreeAll leaves at the same level
Balanced Binary Tree|height(L) − height(R)| ≤ 1 for all nodes

BST properties & operations

// BST property: left < root < right
Node* search(Node* r, int k) {
    if (!r || r->data == k) return r;
    if (k < r->data) return search(r->left, k);
    return search(r->right, k);
}

// Inorder of a BST = sorted ascending order
// BST insert: like search, add at the NULL spot found
// BST delete has 3 cases:
//   1. Leaf              → just remove
//   2. One child          → replace node with its child
//   3. Two children        → replace with inorder successor
//                            (smallest value in the right subtree)

Tree traversals

// Inorder (Left → Root → Right) → sorted order for a BST
void inorder(Node *r) {
    if (!r) return;
    inorder(r->left);
    printf("%d ", r->data);
    inorder(r->right);
}

// Preorder (Root → Left → Right)  → used to copy a tree
// Postorder (Left → Right → Root) → used to delete a tree
// Level order                     → uses a queue (BFS)

Important formulas

PropertyFormula
Max nodes at level i2^i
Max nodes in height-h binary tree2^(h+1) − 1
Min height for n nodesfloor(log₂ n)
Leaf nodes in a full binary treeinternal nodes + 1
n₀ = n₂ + 1leaf count = (degree-2 node count) + 1

PYQ

Inorder traversal of a BST gives nodes in which order?

  • A) Random
  • B) Descending
  • C) Ascending (sorted)
  • D) Level order

Why: BST property: left < root < right. Inorder (L→Root→R) always produces ascending sorted output.

PYQ

A complete binary tree with 15 nodes has height:

  • A) 2
  • B) 3
  • C) 4
  • D) 5

Why: Height = floor(log₂(15)) = floor(3.9) = 3. A perfect binary tree of height 3 has 2⁴−1 = 15 nodes.

PYQ

How many leaf nodes does a full binary tree with 7 internal nodes have?

  • A) 6
  • B) 7
  • C) 8
  • D) 9

Why: For a full binary tree: leaf nodes = internal nodes + 1 = 7 + 1 = 8.

Heaps & priority queues

Heap properties

PropertyMax HeapMin Heap
Root valueLargest elementSmallest element
Parent ruleparent ≥ childrenparent ≤ children
Get min/maxO(1)O(1)
InsertO(log n)O(log n)
Delete rootO(log n)O(log n)
Build heapO(n)O(n)
Heap sortO(n log n)O(n log n)

Heap sort steps

Step 1: Build a max heap from the array — O(n)
        heapify from the last internal node (index n/2 - 1) down to the root

Step 2: Extract the max repeatedly — O(n log n)
        swap root with the last element
        reduce heap size by 1
        heapify the root

Result: ascending sorted array
Space:  O(1) — in-place
Stable: No

Array representation

For a node at index i (1-based):
  Left child  = 2*i
  Right child = 2*i + 1
  Parent      = i/2

For a node at index i (0-based):
  Left child  = 2*i + 1
  Right child = 2*i + 2
  Parent      = (i-1)/2

Applications

ApplicationHeap type
Priority queueMin or max heap
Heap sortMax heap
Dijkstra’s algorithmMin heap
Prim’s algorithmMin heap
K largest elementsMin heap of size k
Median of a streamMax heap + min heap

PYQ

In a max heap stored as an array (1-based), where is the parent of the element at index 6?

  • A) 2
  • B) 3
  • C) 4
  • D) 5

Why: Parent = i/2 = 6/2 = 3 (integer division).

Graphs

Representations

MethodSpaceEdge checkAdd edge
Adjacency MatrixO(V²)O(1)O(1)
Adjacency ListO(V+E)O(degree)O(1)

Use a matrix for dense graphs; a list for sparse graphs.

DFS — cycle detection, topological sort

bool visited[V] = {false};

void DFS(int u, int adj[][V]) {
    visited[u] = true;
    printf("%d ", u);
    for (int v = 0; v < V; v++)
        if (adj[u][v] && !visited[v])
            DFS(v, adj);
}

BFS — level order, shortest path (unweighted)

void BFS(int src, int adj[][V]) {
    bool visited[V] = {false};
    int queue[V], front = 0, rear = 0;
    visited[src] = true;
    queue[rear++] = src;

    while (front < rear) {
        int u = queue[front++];
        printf("%d ", u);
        for (int v = 0; v < V; v++)
            if (adj[u][v] && !visited[v]) {
                visited[v] = true;
                queue[rear++] = v;
            }
    }
}

Shortest path algorithms

AlgorithmWorks onComplexity
BFSUnweighted graphsO(V+E)
DijkstraNon-negative weightsO((V+E) log V)
Bellman-FordNegative weightsO(V·E)
Floyd-WarshallAll pairsO(V³)

Spanning tree algorithms

AlgorithmStrategyComplexity
Prim’sAdd the min edge to a growing treeO(E log V)
Kruskal’sSort edges, then union-findO(E log E)

PYQ

BFS on a graph uses which data structure?

  • A) Stack
  • B) Queue
  • C) Priority queue
  • D) Array

Why: BFS uses a queue (FIFO) to process nodes level by level. DFS uses a stack (or the recursion call stack).

PYQ

Which algorithm finds the shortest path in a graph with negative weights (no negative cycles)?

  • A) Dijkstra
  • B) BFS
  • C) Bellman-Ford
  • D) Prim's

Why: Dijkstra fails with negative weights. Bellman-Ford handles negative weights and also detects negative cycles.

Hashing

Hash table operations

OperationAverageWorst
SearchO(1)O(n)
InsertO(1)O(n)
DeleteO(1)O(n)

Worst case O(n) occurs when all keys hash to the same slot (all collisions).

Collision resolution

MethodHow it worksClustering
ChainingLinked list at each slotNo clustering
Linear probingh(k)+1, +2, … (mod m)Primary clustering
Quadratic probingh(k)+1², +2², … (mod m)Secondary clustering
Double hashingh1(k) + i·h2(k) (mod m)No clustering

Hash functions

Division method:
  h(k) = k % m   (m should be prime)

Multiplication method:
  h(k) = floor(m * (k*A mod 1))   where A ≈ 0.618 (golden ratio)

For strings (djb2):
  hash = 5381;
  while (*str) hash = hash*33 ^ *str++;

Load factor & rehashing

Load factor α = n / m
  n = number of elements
  m = number of slots

When α > 0.7 (typical threshold):
  → rehash into a larger table (2x)
  → re-insert all elements

Chaining:       works even when α > 1
Open addressing: α must stay < 1

PYQ

In open addressing with linear probing, what is the main problem?

  • A) Extra memory
  • B) Primary clustering
  • C) Secondary clustering
  • D) High deletion cost

Why: Linear probing creates primary clustering — long chains of consecutive occupied slots that slow down search and insert.

CDAC C-CAT — top DS exam traps

TrapRule
Stack underflowPopping from an empty stack. A top == -1 check is mandatory.
Queue full (circular)(rear+1)%MAX == front means full, NOT rear == MAX-1.
BST worst caseInserting sorted data into a BST gives O(n) height (degenerate/skewed tree).
BFS vs DFSBFS → queue → shortest path (unweighted). DFS → stack/recursion → cycle detection, topological sort.
Heap is not a BSTA heap only guarantees parent > children (max heap). BST guarantees left < root < right.
Inorder of BSTAlways gives sorted (ascending) output. Preorder = copy tree. Postorder = delete tree.
n₀ = n₂ + 1In any binary tree: leaf nodes = nodes with 2 children + 1. Very common formula question.
Stable vs unstable sortMerge, Bubble, Insertion = stable. Quick, Heap, Selection = NOT stable.
Quick sort worst caseO(n²) when the pivot is always the min or max (e.g. an already-sorted array). Avg is O(n log n).
Merge sort spaceO(n) extra space (needs a temp array). Heap sort is O(1) in-place.
Hash chaining α > 1Chaining allows a load factor above 1. Open addressing requires α < 1.
Floyd cycle — meeting pointSlow and fast pointers meet INSIDE the cycle, not necessarily at its start.
Height vs depthHeight = edges from a node to its deepest leaf. Depth = edges from the root to that node.
Complete BT heightfloor(log₂ n) for n nodes.
Dijkstra + negative edgesDijkstra FAILS with negative weight edges. Use Bellman-Ford instead.
Graph adjacency matrixSpace is always O(V²) regardless of edge count — bad for sparse graphs.

PYQs are indicative of exam style, not guaranteed exact repeats.