DSA_LEARN

<!DOCTYPE html>

DSA Topics Explained
DSA Explained

Arrays

An array is a collection of items stored at contiguous memory locations. It allows fast access using indices.

Syntax (C++):

int arr[5];            // Declaration of array with 5 integers
int arr[] = {1, 2, 3};  // Initialization of array

Traversal Algorithm:

for (int i = 0; i < n; i++) {
    // Access arr[i]
}

Linked Lists

A linked list consists of nodes where each node contains data and a pointer to the next node.

Node Structure (C++):

struct Node {
    int data;
    Node* next;
};

Traversal Algorithm:

Node* curr = head;
while (curr != nullptr) {
    // Process curr->data
    curr = curr->next;
}

Stacks

Stack is a LIFO data structure where elements are added and removed from the top.

Using STL stack (C++):

#include <stack>
std::stack<int> s;
s.push(10);  // Push element
s.pop();     // Pop element

Operations:

push(x)    // Insert element x
pop()       // Remove top element
top()       // Access top element
empty()     // Check if empty

Queues

Queue is a FIFO data structure where elements are added at the rear and removed from the front.

Using STL queue (C++):

#include <queue>
std::queue<int> q;
q.push(10);  // Enqueue
q.pop();     // Dequeue

Operations:

enqueue(x)   // Add element x
dequeue()     // Remove front element
front()       // Access front element
empty()       // Check if empty

Trees

Trees are hierarchical data structures with nodes having children, starting from a root node.

Binary Tree Node (C++):

struct Node {
    int data;
    Node* left;
    Node* right;
};

Inorder Traversal Algorithm:

void inorder(Node* root) {
    if (!root) return;
    inorder(root->left);
    // Process root->data
    inorder(root->right);
}

Graphs

Graphs consist of nodes (vertices) connected by edges; they can be directed or undirected.

Adjacency List (C++):

std::vector<std::vector<int>> adj(n);
adj[u].push_back(v);  // Edge u -> v

Breadth First Search (BFS) Algorithm:

std::queue<int> q;
std::vector<bool> visited(n, false);
q.push(start);
visited[start] = true;

while (!q.empty()) {
    int u = q.front(); q.pop();
    // Process u
    for (auto v : adj[u]) {
        if (!visited[v]) {
            visited[v] = true;
            q.push(v);
        }
    }
}

Sorting Algorithms

Sorting arranges elements in order. Common algorithms include Bubble Sort, Merge Sort, Quick Sort.

Bubble Sort (O(n²)):

for (int i = 0; i < n-1; i++) {
    for (int j = 0; j < n-1-i; j++) {
        if (arr[j] > arr[j+1]) {
            std::swap(arr[j], arr[j+1]);
        }
    }
}

Merge Sort (O(n log n)):

void mergeSort(int arr[], int l, int r);
void merge(int arr[], int l, int m, int r);

Recursively split and merge sorted subarrays.

Quick Sort (O(n log n) avg):

int partition(int arr[], int low, int high);
void quickSort(int arr[], int low, int high);

Partition array around pivot and recursively sort subarrays.

Searching Algorithms

Algorithms to find data. Includes Linear and Binary Search.

Linear Search (O(n)):

for (int i = 0; i < n; i++) {
    if (arr[i] == target) return i;
}
return -1;

Binary Search (O(log n)) (Sorted Array):

int low = 0, high = n - 1;
while (low <= high) {
    int mid = low + (high - low) / 2;
    if (arr[mid] == target) return mid;
    else if (arr[mid] < target) low = mid + 1;
    else high = mid - 1;
}
return -1;

Hashing

Hashes map keys to indices in a table for efficient lookup.

Syntax (C++ STL unordered_map):

#include <unordered_map>
std::unordered_map<int, std::string> hashmap;
hashmap[1] = "one";
auto it = hashmap.find(1);
if (it != hashmap.end()) {
    // Found
}

Concept:

key --hash_function--> index in hash table
Store/retrieve data at that index

Dynamic Programming (DP)

DP solves problems by combining solutions to overlapping subproblems, storing results to avoid recomputation.

Example: Fibonacci (Memoization):

int fib(int n, std::vector<int>& memo) {
    if (n <= 1) return n;
    if (memo[n] != -1) return memo[n];
    memo[n] = fib(n-1, memo) + fib(n-2, memo);
    return memo[n];
}

Example: Fibonacci (Tabulation):

int fib(int n) {
    std::vector<int> dp(n+1);
    dp[0] = 0; dp[1] = 1;
    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i-1] + dp[i-2];
    }
    return dp[n];
}