Algorithms - Learn With Examples https://learnwithexamples.org/category/computer-science-concepts/algorithms/ Lets Learn things the Easy Way Fri, 20 Jun 2025 16:09:37 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.1 https://i0.wp.com/learnwithexamples.org/wp-content/uploads/2024/09/Learn-with-examples.png?fit=32%2C32&ssl=1 Algorithms - Learn With Examples https://learnwithexamples.org/category/computer-science-concepts/algorithms/ 32 32 228207193 Top 10 Algorithms Every Programmer Should Know https://learnwithexamples.org/top-10-algorithms-every-programmer-should-know/ https://learnwithexamples.org/top-10-algorithms-every-programmer-should-know/#respond Fri, 20 Jun 2025 16:09:33 +0000 https://learnwithexamples.org/?p=448 Also check: Understanding the Magic Behind Computers

The post Top 10 Algorithms Every Programmer Should Know appeared first on Learn With Examples.

]]>
Top 10 Algorithms Every Programmer Should Know

Master the Fundamentals

Algorithms are the backbone of computer science and programming. Understanding these fundamental algorithms will make you a better programmer, improve your problem-solving skills, and help you excel in technical interviews. This comprehensive guide covers the top 10 algorithms every programmer should master, complete with interactive examples and detailed explanations.

1. Binary Search Algorithm

Binary search is one of the most efficient searching algorithms for sorted arrays. It works by repeatedly dividing the search interval in half, comparing the target value with the middle element, and eliminating half of the remaining elements in each iteration.

How Binary Search Works:

  1. Start with the entire sorted array
  2. Find the middle element
  3. If the middle element equals the target, return its index
  4. If the target is less than the middle element, search the left half
  5. If the target is greater than the middle element, search the right half
  6. Repeat until the element is found or the array is exhausted
function binarySearch(arr, target) { let left = 0; let right = arr.length - 1; while (left <= right) { let mid = Math.floor((left + right) / 2); if (arr[mid] === target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; // Element not found }

Interactive Binary Search Demo

Time Complexity Space Complexity Best Case Worst Case
O(log n) O(1) O(1) O(log n)

2. Quick Sort Algorithm

Quick Sort is a highly efficient divide-and-conquer sorting algorithm. It works by selecting a 'pivot' element and partitioning the other elements into two sub-arrays according to whether they are less than or greater than the pivot.

Key Insight: Quick Sort's average-case performance is excellent, making it one of the most popular sorting algorithms in practice.
function quickSort(arr, low = 0, high = arr.length - 1) { if (low < high) { let pivotIndex = partition(arr, low, high); quickSort(arr, low, pivotIndex - 1); quickSort(arr, pivotIndex + 1, high); } return arr; } function partition(arr, low, high) { let pivot = arr[high]; let i = low - 1; for (let j = low; j < high; j++) { if (arr[j] < pivot) { i++; [arr[i], arr[j]] = [arr[j], arr[i]]; } } [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]]; return i + 1; }

Interactive Quick Sort Demo

Average Case Best Case Worst Case Space Complexity
O(n log n) O(n log n) O(n²) O(log n)

3. Merge Sort Algorithm

Merge Sort is a stable, divide-and-conquer algorithm that divides the array into halves, sorts them separately, and then merges them back together. It guarantees O(n log n) time complexity in all cases.

function mergeSort(arr) { if (arr.length <= 1) { return arr; } const mid = Math.floor(arr.length / 2); const left = mergeSort(arr.slice(0, mid)); const right = mergeSort(arr.slice(mid)); return merge(left, right); } function merge(left, right) { let result = []; let leftIndex = 0; let rightIndex = 0; while (leftIndex < left.length && rightIndex < right.length) { if (left[leftIndex] < right[rightIndex]) { result.push(left[leftIndex]); leftIndex++; } else { result.push(right[rightIndex]); rightIndex++; } } return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex)); }

Interactive Merge Sort Demo

4. Depth-First Search (DFS)

DFS is a graph traversal algorithm that explores as far as possible along each branch before backtracking. It can be implemented using recursion or an explicit stack.

// Recursive DFS for adjacency list representation function dfsRecursive(graph, node, visited = new Set()) { visited.add(node); console.log(node); for (let neighbor of graph[node] || []) { if (!visited.has(neighbor)) { dfsRecursive(graph, neighbor, visited); } } } // Iterative DFS using stack function dfsIterative(graph, startNode) { const visited = new Set(); const stack = [startNode]; while (stack.length > 0) { const node = stack.pop(); if (!visited.has(node)) { visited.add(node); console.log(node); for (let neighbor of graph[node] || []) { if (!visited.has(neighbor)) { stack.push(neighbor); } } } } }

Interactive DFS Demo

Graph representation: A → [B, C], B → [D, E], C → [F], D → [], E → [F], F → []

5. Breadth-First Search (BFS)

BFS explores all vertices at the current depth before moving to vertices at the next depth level. It uses a queue data structure and is particularly useful for finding the shortest path in unweighted graphs.

function bfs(graph, startNode) { const visited = new Set(); const queue = [startNode]; const result = []; visited.add(startNode); while (queue.length > 0) { const node = queue.shift(); result.push(node); for (let neighbor of graph[node] || []) { if (!visited.has(neighbor)) { visited.add(neighbor); queue.push(neighbor); } } } return result; } // BFS for shortest path function bfsShortestPath(graph, start, target) { const queue = [[start, [start]]]; const visited = new Set([start]); while (queue.length > 0) { const [node, path] = queue.shift(); if (node === target) { return path; } for (let neighbor of graph[node] || []) { if (!visited.has(neighbor)) { visited.add(neighbor); queue.push([neighbor, [...path, neighbor]]); } } } return null; // No path found }

Interactive BFS Demo

6. Dynamic Programming - Fibonacci Sequence

Dynamic Programming is an optimization technique that solves complex problems by breaking them down into simpler subproblems. The Fibonacci sequence is a classic example where DP can dramatically improve performance.

// Naive recursive approach - O(2^n) function fibonacciNaive(n) { if (n <= 1) return n; return fibonacciNaive(n - 1) + fibonacciNaive(n - 2); } // Dynamic Programming approach - O(n) function fibonacciDP(n) { if (n <= 1) return n; const dp = [0, 1]; for (let i = 2; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; } // Space-optimized DP - O(1) space function fibonacciOptimized(n) { if (n <= 1) return n; let prev = 0, curr = 1; for (let i = 2; i <= n; i++) { const temp = curr; curr = prev + curr; prev = temp; } return curr; }

Interactive Fibonacci Demo

7. Dijkstra's Shortest Path Algorithm

Dijkstra's algorithm finds the shortest path between nodes in a weighted graph. It's widely used in networking protocols, GPS navigation, and social networking applications.

function dijkstra(graph, start) { const distances = {}; const visited = new Set(); const previous = {}; // Initialize distances for (let node in graph) { distances[node] = node === start ? 0 : Infinity; previous[node] = null; } while (visited.size < Object.keys(graph).length) { // Find unvisited node with minimum distance let minNode = null; for (let node in distances) { if (!visited.has(node) && (minNode === null || distances[node] < distances[minNode])) { minNode = node; } } if (minNode === null || distances[minNode] === Infinity) break; visited.add(minNode); // Update distances to neighbors for (let neighbor in graph[minNode]) { const distance = distances[minNode] + graph[minNode][neighbor]; if (distance < distances[neighbor]) { distances[neighbor] = distance; previous[neighbor] = minNode; } } } return { distances, previous }; }

Interactive Dijkstra's Demo

Sample graph: A→B(4), A→C(2), B→C(1), B→D(5), C→D(8), C→E(10), D→E(2)

8. Hash Table Implementation

Hash tables provide average O(1) time complexity for insertions, deletions, and lookups. They use a hash function to map keys to array indices, making them incredibly efficient for many operations.

class HashTable { constructor(size = 10) { this.size = size; this.buckets = new Array(size).fill(null).map(() => []); } hash(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash += key.charCodeAt(i); } return hash % this.size; } set(key, value) { const index = this.hash(key); const bucket = this.buckets[index]; // Check if key already exists for (let i = 0; i < bucket.length; i++) { if (bucket[i][0] === key) { bucket[i][1] = value; return; } } // Add new key-value pair bucket.push([key, value]); } get(key) { const index = this.hash(key); const bucket = this.buckets[index]; for (let [k, v] of bucket) { if (k === key) return v; } return undefined; } delete(key) { const index = this.hash(key); const bucket = this.buckets[index]; for (let i = 0; i < bucket.length; i++) { if (bucket[i][0] === key) { bucket.splice(i, 1); return true; } } return false; } }

Interactive Hash Table Demo

9. Binary Tree Traversal

Binary tree traversal algorithms are fundamental for working with tree data structures. The three main traversal methods are in-order, pre-order, and post-order traversal.

class TreeNode { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } // In-order traversal (Left, Root, Right) function inorderTraversal(root, result = []) { if (root !== null) { inorderTraversal(root.left, result); result.push(root.val); inorderTraversal(root.right, result); } return result; } // Pre-order traversal (Root, Left, Right) function preorderTraversal(root, result = []) { if (root !== null) { result.push(root.val); preorderTraversal(root.left, result); preorderTraversal(root.right, result); } return result; } // Post-order traversal (Left, Right, Root) function postorderTraversal(root, result = []) { if (root !== null) { postorderTraversal(root.left, result); postorderTraversal(root.right, result); result.push(root.val); } return result; }

Interactive Binary Tree Traversal Demo

Sample tree structure:

1
2      3
4 5   6 7

10. Two Pointers Technique

The two pointers technique is a powerful algorithmic approach used to solve array and string problems efficiently. It involves using two pointers that move through the data structure to find a solution.

// Two Sum - Sorted Array function twoSumSorted(numbers, target) { let left = 0; let right = numbers.length - 1; while (left < right) { const sum = numbers[left] + numbers[right]; if (sum === target) { return [left, right]; } else if (sum < target) { left++; } else { right--; } } return [-1, -1]; } // Remove Duplicates from Sorted Array function removeDuplicates(nums) { if (nums.length === 0) return 0; let slow = 0; for (let fast = 1; fast < nums.length; fast++) { if (nums[fast] !== nums[slow]) { slow++; nums[slow] = nums[fast]; } } return slow + 1; } // Palindrome Check function isPalindrome(s) { s = s.toLowerCase().replace(/[^a-z0-9]/g, ''); let left = 0; let right = s.length - 1; while (left < right) { if (s[left] !== s[right]) { return false; } left++; right--; } return true; }

Interactive Two Pointers Demo

Conclusion

Mastering these 10 fundamental algorithms will significantly improve your programming skills and problem-solving abilities. Each algorithm has its unique strengths and use cases:

  • Binary Search: Efficient searching in sorted data
  • Quick Sort & Merge Sort: Fast and reliable sorting algorithms
  • DFS & BFS: Essential graph traversal techniques
  • Dynamic Programming: Optimization for overlapping subproblems
  • Dijkstra's Algorithm: Shortest path in weighted graphs
  • Hash Tables: Fast data retrieval and storage
  • Tree Traversal: Systematic exploration of tree structures
  • Two Pointers: Efficient array and string manipulation

Regular practice with these algorithms will help you recognize patterns in complex problems and choose the most appropriate solution approach. Remember that understanding the underlying principles is more important than memorizing the code – focus on when and why to use each algorithm.

Continue practicing these algorithms with different variations and edge cases. The interactive examples provided here are just the beginning – try implementing these algorithms in your preferred programming language and experiment with different inputs to deepen your understanding.

Also check: Understanding the Magic Behind Computers

The post Top 10 Algorithms Every Programmer Should Know appeared first on Learn With Examples.

]]>
https://learnwithexamples.org/top-10-algorithms-every-programmer-should-know/feed/ 0 448
A Beginner’s Guide to Understanding the Magic Behind Computers – Algorithms https://learnwithexamples.org/lets-learn-algorithm/ https://learnwithexamples.org/lets-learn-algorithm/#respond Sat, 27 Jan 2024 08:02:50 +0000 https://learnwithexamples.org/?p=26 Welcome to the enchanting world of algorithms, the secret sauce that powers the digital realm! If you’ve ever wondered how computers make decisions, solve problems, or perform seemingly complex tasks,…

The post A Beginner’s Guide to Understanding the Magic Behind Computers – Algorithms appeared first on Learn With Examples.

]]>

Welcome to the enchanting world of algorithms, the secret sauce that powers the digital realm! If you’ve ever wondered how computers make decisions, solve problems, or perform seemingly complex tasks, you’re in for a treat. In this whimsical journey, we’ll embark on an adventure to demystify algorithms for beginners, using simple examples that will make you the hero of your own coding story.

Chapter 1: The Quest Begins – What is an Algorithm?

Our tale begins with a simple question: What is an algorithm? Imagine you’re in a magical kitchen, trying to bake a cake. An algorithm, in its essence, is nothing more than a step-by-step recipe for achieving a specific goal. Just as a recipe guides you through the process of creating a delicious cake, an algorithm guides a computer through a series of steps to accomplish a task.

Chapter 2: The Fairy Tale of Sorting – Bubble Sort

As our journey unfolds, we encounter the fairy tale of sorting. Picture a row of enchanted books in a library, each with a unique story. Bubble Sort, our magical librarian, wants to organize them in alphabetical order. Here’s how the spell works:

  1. Start at the beginning of the row.
  2. Compare the first two books.
  3. If they are in the correct order, move to the next pair. If not, swap them.
  4. Repeat until the entire row is sorted.

In this whimsical dance, Bubble Sort keeps comparing and swapping until the books find their rightful place. While this sorting method may seem charming, it’s not the most efficient for large collections of books.

Chapter 3: The Maze of Searching – Binary Search

Now, let’s delve into the mysterious maze of searching with Binary Search. Imagine you’re in a magical forest with countless doors. Behind one of them lies the treasure you seek. Binary Search is your guide:

  1. Start at the middle door.
  2. If the treasure is behind that door, rejoice! If not, narrow your search to the left or right half, depending on whether the treasure is smaller or larger.
  3. Repeat until you find the treasure.

Binary Search cuts the possibilities in half with each attempt, making it a swift and efficient guide through the magical forest of information.

Chapter 4: The Enchanted Garden of Recursion – Factorial

As our adventure continues, we stumble upon an enchanted garden where the concept of recursion blooms like mystical flowers. Consider calculating the factorial of a number, an enchanting mathematical trick:

  1. If the number is 0 or 1, the factorial is 1.
  2. Otherwise, the factorial is the number multiplied by the factorial of the number minus 1.

This recursive dance continues until we reach the base case of 0 or 1, unraveling the magic of Factorial in the garden of numbers.

Chapter 5: The Puzzle of Greedy Algorithms – Knapsack Problem

In the heart of the algorithmic kingdom, we encounter a challenging puzzle known as the Knapsack Problem. Imagine you’re a treasure hunter, faced with a collection of treasures each with its own weight and value. Your goal is to maximize the value of the treasures you carry in your magical knapsack, but there’s a weight limit. Enter Greedy Algorithms, your trusty companions:

  1. Sort the treasures by their value-to-weight ratio.
  2. Add treasures to the knapsack in order until it’s full.

While Greedy Algorithms may not always find the absolute best solution, they offer a quick and practical approach to the Knapsack Problem.

Chapter 6: The Labyrinth of Dynamic Programming – Fibonacci Sequence

Our journey takes us through the labyrinth of Dynamic Programming, where we unravel the mystery of the Fibonacci sequence. Picture a magical staircase, and you want to know how many ways you can climb it. Dynamic Programming provides the answer:

  1. If there’s only one step, there’s only one way to climb.
  2. If there are two steps, there are two ways: climb one step twice or take two steps at once.
  3. For more steps, each step can be reached by adding the ways to reach the previous two steps.

Dynamic Programming breaks down complex problems into simpler subproblems, making the labyrinth of algorithms more manageable.


As our algorithmic adventure comes to a close, we’ve explored the enchanting world of algorithms through the lens of fairy tales and magical scenarios. From the sorting spells of Bubble Sort to the treasure hunts with Binary Search, from the recursive dances of Factorial to the strategic companionship of Greedy Algorithms and the labyrinthine wisdom of Dynamic Programming – each algorithm tells a unique story.

Remember, dear reader, algorithms are not mere lines of code; they are the enchanting tales that guide computers through the magical realm of problem-solving. Embrace the magic, let your curiosity soar, and may your coding adventures be filled with wonder and discovery!

For more learning articles keep visiting Learn with examples

The post A Beginner’s Guide to Understanding the Magic Behind Computers – Algorithms appeared first on Learn With Examples.

]]>
https://learnwithexamples.org/lets-learn-algorithm/feed/ 0 26