Definition

Linear data structure storing elements in contiguous memory, accessed via index.

Why Useful
  • Constant-time random access: O(1)
  • Cache-friendly: Improves performance
Software Applications
  • Image Processing: Images stored as 2D arrays (pixels)
  • Databases: Fixed indexing tables
  • Operating Systems: Page tables in memory management
Real-world Analogy

Apartment building with numbered flats - you can go directly to Flat #203 without checking others.

// Array - Static & Dynamic #include <iostream> #include <vector> using namespace std; int main() { // Static array int arr[5] = {10, 20, 30, 40, 50}; // Dynamic array (vector) vector<int> vec = {1, 2, 3, 4, 5}; // Access - O(1) cout << "arr[2]: " << arr[2] << endl; cout << "vec[2]: " << vec[2] << endl; return 0; }
// Array - Static & Dynamic import java.util.ArrayList; public class ArrayExample { public static void main(String[] args) { // Static array int[] arr = {10, 20, 30, 40, 50}; // Dynamic array (ArrayList) ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); // Access - O(1) System.out.println("arr[2]: " + arr[2]); System.out.println("list[2]: " + list.get(2)); } }
# Array - List in Python # Static-like list arr = [10, 20, 30, 40, 50] # Dynamic list vec = [1, 2, 3, 4, 5] vec.append(6) # Access - O(1) print(f"arr[2]: {arr[2]}") print(f"vec[2]: {vec[2]}")
Definition

Sequence of nodes where each stores data and pointer to next node.

Why Useful
  • Efficient insertions/deletions: O(1) compared to arrays
  • Dynamic size: No need to know size in advance
Applications
  • Music Playlists: Next/Previous navigation
  • Undo/Redo: Action history
  • Memory Management: Free block lists
Real-world Analogy

Train coaches - easy to attach/detach without shifting all others.

// Linked List - Node Structure #include <iostream> using namespace std; struct Node { int data; Node* next; Node(int val) : data(val), next(nullptr) {} }; int main() { Node* head = new Node(10); head->next = new Node(20); head->next->next = new Node(30); Node* temp = head; while (temp != nullptr) { cout << temp->data << " -> "; temp = temp->next; } cout << "NULL" << endl; return 0; }
// Linked List - Node Structure public class LinkedListExample { static class Node { int data; Node next; Node(int val) { data = val; next = null; } } public static void main(String[] args) { Node head = new Node(10); head.next = new Node(20); head.next.next = new Node(30); Node temp = head; while (temp != null) { System.out.print(temp.data + " -> "); temp = temp.next; } System.out.println("NULL"); } }
# Linked List - Node Structure class Node: def __init__(self, val): self.data = val self.next = None head = Node(10) head.next = Node(20) head.next.next = Node(30) temp = head while temp: print(temp.data, end=" -> ") temp = temp.next print("NULL")
Principle

LIFO - Last In First Out

Why Useful
  • Natural for "last done, first undone" problems
  • Easy backtracking
Applications
  • Function Calls: Call stack in programming
  • Browser: Back button history
  • Compilers: Expression evaluation
Real-world Analogy

Stack of plates - last plate placed is first removed.

// Stack - LIFO Structure #include <iostream> #include <stack> using namespace std; int main() { stack<int> st; st.push(10); st.push(20); st.push(30); cout << "Top: " << st.top() << endl; // 30 st.pop(); cout << "After pop: " << st.top() << endl; // 20 cout << "Size: " << st.size() << endl; return 0; }
// Stack - LIFO Structure import java.util.Stack; public class StackExample { public static void main(String[] args) { Stack<Integer> st = new Stack<>(); st.push(10); st.push(20); st.push(30); System.out.println("Top: " + st.peek()); // 30 st.pop(); System.out.println("After pop: " + st.peek()); // 20 System.out.println("Size: " + st.size()); } }
# Stack - LIFO using list st = [] st.append(10) st.append(20) st.append(30) print(f"Top: {st[-1]}") # 30 st.pop() print(f"After pop: {st[-1]}") # 20 print(f"Size: {len(st)}")
Principle

FIFO - First In First Out

Why Useful
  • Ensures fairness (first come, first served)
Applications
  • CPU Scheduling: Process queue in OS
  • Printers: Print job queue
  • Networking: Packet transmission order
Real-world Analogy

Queue at ticket counter - first person in line is served first.

// Queue - FIFO Structure #include <iostream> #include <queue> using namespace std; int main() { queue<int> q; q.push(10); q.push(20); q.push(30); cout << "Front: " << q.front() << endl; // 10 q.pop(); cout << "After pop: " << q.front() << endl; // 20 cout << "Size: " << q.size() << endl; return 0; }
// Queue - FIFO Structure import java.util.LinkedList; import java.util.Queue; public class QueueExample { public static void main(String[] args) { Queue<Integer> q = new LinkedList<>(); q.offer(10); q.offer(20); q.offer(30); System.out.println("Front: " + q.peek()); // 10 q.poll(); System.out.println("After poll: " + q.peek()); // 20 System.out.println("Size: " + q.size()); } }
# Queue - FIFO using deque from collections import deque q = deque() q.append(10) q.append(20) q.append(30) print(f"Front: {q[0]}") # 10 q.popleft() print(f"After pop: {q[0]}") # 20 print(f"Size: {len(q)}")
Definition

Hierarchical structure with root and children nodes.

Why Useful
  • Efficient search/insert/delete: O(log n) in balanced trees
  • Perfect for hierarchical data
Applications
  • File Systems: Directories and subdirectories
  • Databases: B-Trees for indexing
  • HTML DOM: Web page structure
Real-world Analogy

Family tree - grandparents → parents → children.

// Binary Tree - Node Structure #include <iostream> using namespace std; struct TreeNode { int data; TreeNode* left; TreeNode* right; TreeNode(int val) : data(val), left(nullptr), right(nullptr) {} }; int main() { TreeNode* root = new TreeNode(10); root->left = new TreeNode(5); root->right = new TreeNode(15); root->left->left = new TreeNode(3); root->left->right = new TreeNode(7); cout << "Root: " << root->data << endl; cout << "Left: " << root->left->data << endl; return 0; }
// Binary Tree - Node Structure public class TreeExample { static class TreeNode { int data; TreeNode left, right; TreeNode(int val) { data = val; } } public static void main(String[] args) { TreeNode root = new TreeNode(10); root.left = new TreeNode(5); root.right = new TreeNode(15); root.left.left = new TreeNode(3); root.left.right = new TreeNode(7); System.out.println("Root: " + root.data); System.out.println("Left: " + root.left.data); } }
# Binary Tree - Node Structure class TreeNode: def __init__(self, val): self.data = val self.left = None self.right = None root = TreeNode(10) root.left = TreeNode(5) root.right = TreeNode(15) root.left.left = TreeNode(3) root.left.right = TreeNode(7) print(f"Root: {root.data}") print(f"Left: {root.left.data}")
Definition

Nodes (vertices) connected by edges.

Why Useful
  • Models relationships and networks
  • Algorithms for shortest path, connectivity
Applications
  • Google Maps: Shortest path algorithms
  • Social Networks: Friend connections
  • Networking: Router connections
Real-world Analogy

City map - intersections are nodes, roads are edges.

// Graph - Adjacency List #include <iostream> #include <vector> using namespace std; int main() { int V = 5; vector<vector<int>> adj(V); adj[0].push_back(1); adj[1].push_back(0); adj[0].push_back(2); adj[2].push_back(0); adj[1].push_back(3); adj[3].push_back(1); for (int i = 0; i < V; i++) { cout << i << " -> "; for (int j : adj[i]) cout << j << " "; cout << endl; } return 0; }
// Graph - Adjacency List import java.util.*; public class GraphExample { public static void main(String[] args) { int V = 5; List<List<Integer>> adj = new ArrayList<>(); for (int i = 0; i < V; i++) adj.add(new ArrayList<>()); adj.get(0).add(1); adj.get(1).add(0); adj.get(0).add(2); adj.get(2).add(0); adj.get(1).add(3); adj.get(3).add(1); for (int i = 0; i < V; i++) { System.out.print(i + " -> "); for (int j : adj.get(i)) System.out.print(j + " "); System.out.println(); } } }
# Graph - Adjacency List from collections import defaultdict adj = defaultdict(list) adj[0].append(1); adj[1].append(0) adj[0].append(2); adj[2].append(0) adj[1].append(3); adj[3].append(1) for i in range(5): print(f"{i} -> {' '.join(map(str, adj[i]))}")
Definition

Key-value pairs with O(1) average lookup.

Why Useful
  • O(1) average time: For search, insert, delete
  • Perfect for caching and quick lookups
Applications
  • Caching: Fast data retrieval
  • Databases: Quick record lookup
  • Compilers: Symbol tables
Real-world Analogy

Dictionary - word (key) maps to definition (value).

// HashMap - unordered_map #include <iostream> #include <unordered_map> using namespace std; int main() { unordered_map<string, int> map; map["Alice"] = 25; map["Bob"] = 30; map["Charlie"] = 35; cout << "Alice: " << map["Alice"] << endl; if (map.find("Bob") != map.end()) cout << "Bob found!" << endl; cout << "Size: " << map.size() << endl; return 0; }
// HashMap - Java import java.util.HashMap; public class HashMapExample { public static void main(String[] args) { HashMap<String, Integer> map = new HashMap<>(); map.put("Alice", 25); map.put("Bob", 30); map.put("Charlie", 35); System.out.println("Alice: " + map.get("Alice")); if (map.containsKey("Bob")) System.out.println("Bob found!"); System.out.println("Size: " + map.size()); } }
# HashMap - dict in Python map = { "Alice": 25, "Bob": 30, "Charlie": 35 } print(f"Alice: {map['Alice']}") if "Bob" in map: print("Bob found!") print(f"Size: {len(map)}")
Arrays
  • Video frames storage
  • Comments list
  • Thumbnail rendering
Linked Lists
  • Playlists (next/previous)
  • Watch history navigation
Stack
  • Undo/Redo in video editor
  • Back button navigation
Queue
  • Video upload processing
  • Frame buffering
Trees
  • Category/subcategory structure
  • Comment threads (nested replies)
Graphs
  • Recommendation system
  • Social connections
HashMap
  • Video metadata caching
  • User session management
Heaps
  • Trending videos (priority)
  • Live stream packet management