Heap Sort

Think of building a sandcastle and carefully placing each handful of sand to get the highest, perfect cone. Heap Sort works similarly, arranging data like a pyramid, ensuring the “biggest” (or “smallest”, depending on sorting order) element is always on top.

Process

Heap Sort, as the name suggests, involves creating and manipulating a special data structure called a heap to achieve sorted results. But don’t worry, you don’t need actual shovels and sandcastles for this! Let’s delve into the steps:

1. Heapify the Data: Imagine your data as a pile of pebbles. Heap Sort starts by transforming this pile into a “heap,” which resembles a pyramid-like structure. In this pyramid, the element at the top (the “root”) is always the “biggest” (or “smallest,” depending on the sorting order). Elements are carefully arranged based on their values to maintain this property.

2. Extract the “Biggest” Pebble: Just like picking the biggest pebble for your sandcastle, Heap Sort removes the element at the root (the “biggest” in this case) and places it aside. Remember, the heap property ensures this is indeed the largest element!

3. Maintain the Heap: But removing the top pebble disrupts the heap’s structure. Fear not! Heap Sort employs a clever technique called sifting. It replaces the empty root position with another element from the heap and “sifts” it down until the heap property is restored, ensuring the new root is indeed the “biggest.”

4. Repeat and Conquer: This process of extracting the “biggest” element, sifting, and restoring the heap continues until all elements are processed. By the end, the extracted elements, placed in the order they were removed, form the sorted list!

Pseudo Code

Code
function heapSort(array):
  # Build a max-heap from the input array
  buildMaxHeap(array)

  # Repeatedly extract the root (largest element) and swap it with the last element
  for i in range(len(array) - 1, 0, -1):
    swap(array[0], array[i])
    # Maintain the heap property for the remaining elements
    maxHeapify(array, 0, i)

# Functions for building and maintaining the max-heap

function buildMaxHeap(array):
  # Start from the last non-leaf node and sift downwards
  for i in range(len(array) // 2 - 1, -1, -1):
    maxHeapify(array, i, len(array))

function maxHeapify(array, root, heapSize):
  # Compare the root with its children and swap if necessary
  largest = root
  leftChild = 2 * root + 1
  rightChild = 2 * root + 2

  # Find the largest element among root, left child, and right child
  if leftChild < heapSize and array[leftChild] > array[largest]:
    largest = leftChild
  if rightChild < heapSize and array[rightChild] > array[largest]:
    largest = rightChild

  # Swap the root with the largest element if necessary
  if largest != root:
    swap(array[largest], array[root])
    # Recursively heapify the affected sub-tree
    maxHeapify(array, largest, heapSize)

# Swapping function
function swap(a, b):
  temp = a
  a = b
  b = temp
Explanation
  • The heapSort function takes an array as input.
  • The buildMaxHeap function builds a max-heap from the array, ensuring the element at the root is always the largest.
  • The maxHeapify function maintains the heap property by comparing the root element with its children and swapping if necessary.
  • The main loop of heapSort repeatedly extracts the root (largest element) and swaps it with the last element, reducing the heap size by 1 in each iteration.
  • The maxHeapify function is called again after each swap to maintain the heap property for the remaining elements.
  • The swap function simply exchanges the values of two elements.

Implementation

Kotlin

Golang

Quick Sort: The Speed Demon

Imagine sorting a room full of toys by color. Instead of meticulously comparing each toy, Quick Sort picks one (the “pivot”) and throws it like a ball, creating partitions based on colors “faster than light.” That’s the essence of Quick Sort, partitioning and conquering data with speed and a hint of playful chaos.

Process

Quick Sort, true to its name, lives up to its reputation for speed. But unlike a chaotic mess, its efficiency lies in a well-defined strategy: partitioning and conquering. Let’s delve into the steps of this whirlwind sorting dance:

1. Choose a Pivot: Imagine the data as a group of people waiting in line. Quick Sort picks one person (the pivot) and positions them somewhere in the line. This pivot isn’t random; it can be the first, last, or even a median element.

2. Partition the Line: Now comes the magic! Quick Sort iterates through the line, comparing each person to the pivot. Those shorter than the pivot move to one side, and those taller move to the other. Essentially, the line gets divided into two sections based on the pivot’s height.

3. Conquer and Repeat: But wait, the line isn’t sorted yet! Both the shorter and taller groups, though smaller now, might still be unsorted. So, Quick Sort recursively applies the same “choose-pivot-partition” strategy to each group, further dividing and conquering until each group has only one person (sorted!).

4. Merge and Conquer: Finally, when all groups have just one person (sorted!), Quick Sort meticulously merges them back together in the correct order, ensuring the entire line is now sorted from shortest to tallest (or vice versa, depending on how you define “shorter”).

Pseudo Code

Code
function quickSort(array, start, end):
  # Base case: sub-array with 0 or 1 element is already sorted
  if start >= end:
    return

  # Choose a pivot element (e.g., last element)
  pivot = array[end]

  # Partition the array around the pivot
  partitionIndex = partition(array, start, end, pivot)

  # Recursively sort the sub-arrays before and after the partition
  quickSort(array, start, partitionIndex - 1)
  quickSort(array, partitionIndex + 1, end)

function partition(array, start, end, pivot):
  # Initialize index variables
  i = start - 1
  for j in range(start, end):
    if array[j] <= pivot:
      i += 1
      # Swap elements at i and j
      swap(array[i], array[j])
  # Swap pivot element with element at i + 1 (now the partition index)
  swap(array[i + 1], array[end])
  return i + 1

function swap(a, b):
  # Swap the values of elements a and b
  temp = a
  a = b
  b = temp
Explanation
  1. quickSort(array, start, end): This function takes a sub-array (defined by start and end indices) and sorts it using Quick Sort.
  2. Base case: If the sub-array has 0 or 1 element, it’s already sorted and the function returns.
  3. Choose a pivot: The function selects a pivot element (e.g., the last element).
  4. Partition: The partition function rearranges the array elements:
    • Elements less than or equal to the pivot are moved to the left side.
    • Elements greater than the pivot are moved to the right side.
    • The pivot element is placed at the partition index.
  5. Recursive calls: The function recursively calls itself to sort the sub-arrays before and after the partition, excluding the pivot.
  6. swap(a, b): This function swaps the values of two elements.

Implementation

Kotlin

Golang

Merge Sort

Imagine chopping a messy pile of vegetables into smaller pieces, sorting each pile individually, and then merging them back into a perfectly organized whole. That’s the essence of Merge Sort, dividing, sorting, and conquering data to achieve order.

Process

Merge Sort, unlike its comparison-based counterparts, takes a divide-and-conquer approach, resembling how a ruler conquers territories! Let’s dive into the steps:

1. Divide: Imagine the data as a kingdom waiting to be organized. The king (Merge Sort) divides the kingdom (data) into smaller provinces (sub-lists) of roughly equal size.

2. Conquer: Each province undergoes its own mini-conquest. If a province has only one element (citizen), it’s already sorted! Otherwise, the algorithm recursively divides and conquers each province further, breaking them down into even smaller units until each has only one element.

3. Merge and Rule: Once all provinces are single-element kingdoms, the real merging magic begins. The algorithm starts from the smallest conquered provinces and strategically combines them. Imagine two conquered provinces (sorted sub-lists) merging like neighboring kingdoms, carefully comparing and placing citizens (elements) in their rightful order to form a larger, sorted province.

4. Repeat and Expand: This merging continues, combining two sorted provinces at a time, creating larger and larger sorted territories. It’s like the conquered provinces forming alliances, growing in size and order until the entire kingdom (data) is united under the banner of a single, perfectly sorted list.

Pseudo Code

Code
function mergeSort(array):
  if length(array) <= 1:
    return array

  mid = floor(length(array) / 2)
  left = mergeSort(subarray(array, 0, mid))
  right = mergeSort(subarray(array, mid + 1, length(array)))

  return merge(left, right)

function merge(left, right):
  merged = []
  while length(left) > 0 and length(right) > 0:
    if first element of left <= first element of right:
      append first element of left to merged
      remove first element from left
    else:
      append first element of right to merged
      remove first element from right
  append remaining elements of left to merged
  append remaining elements of right to merged
  return merged

function subarray(array, start, end):
  # Creates a new subarray from the original array with specified start and end indices
  new_array = []
  for i in range(start, end):
    append element at index i of array to new_array
  return new_array
Explanation

mergeSort(array):

  • if length(array) <= 1: If the array has only one element or less, it’s already considered sorted and returned as-is.
  • mid = floor(length(array) / 2): Calculates the middle index of the array for dividing it into approximately equal halves.
  • left = mergeSort(subarray(array, 0, mid)): Recursively calls mergeSort on the left half of the array (from index 0 to mid-1).
  • right = mergeSort(subarray(array, mid + 1, length(array))): Recursively calls mergeSort on the right half of the array (from index mid+1 to the end).
  • return merge(left, right): Calls the merge function to combine the two sorted halves (left and right) into a single sorted array and returns it.

merge(left, right):

  • merged = []: Creates an empty array to store the merged result.
  • while length(left) > 0 and length(right) > 0: Continues the loop as long as both halves have elements left.
    • if first element of left <= first element of right:
      • append first element of left to merged: Adds the smaller element from the left half to the merged array.
      • remove first element from left: Removes the added element from the left half.
    • else:
      • append first element of right to merged: Adds the smaller element from the right half to the merged array.
      • remove first element from right: Removes the added element from the right half.
  • append remaining elements of left to merged: Appends any remaining elements in the left half to the merged array.
  • append remaining elements of right to merged: Appends any remaining elements in the right half to the merged array.
  • return merged: Returns the final sorted array after merging both halves.

subarray(array, start, end):

  • new_array = []: Creates a new empty array.
  • for i in range(start, end): Iterates through the elements from the specified start index to (but not including) the end index.
    • append element at index i of array to new_array: Adds the element at the current index (i) from the original array to the new_array.
  • return new_array: Returns the newly created subarray containing the specified elements.

Implementations

Kotlin

Golang

World Trigger: Review

Have you ever yearned for an anime that seamlessly blends thrilling tactical battles with a captivating world shrouded in mystery? Look no further than World Trigger, where humanity stands defiant against enigmatic threats from another dimension.

Forget your typical shonen fare; this series delves into complex strategies and teamwork, where victory hinges on quick thinking and well-coordinated manoeuvres. But beyond the exhilarating clashes lies a fascinating world waiting to be unravelled. Prepare to be drawn into a society built around a unique technology, where individuals discover hidden strengths and forge unlikely alliances.

Genre and Audience

World Trigger transcends the boundaries of a single genre, offering a multifaceted experience that caters to diverse tastes. Buckle up for sci-fi with a strategic twist!

Story and Structure

Unlike typical shonen fare that throws you headfirst into action, World Trigger takes a more deliberate approach. Prepare for:

Immersive World-Building: The story carefully constructs its universe, meticulously introducing the organization tasked with defending humanity, their specialized technology, and the enigmatic threat they face. This initial investment in building the world provides a strong foundation for later understanding and emotional engagement.

Episodic with an Overarching Arc: Each episode presents engaging challenges and character interactions, offering satisfying standalone stories. However, a subtle overarching narrative weaves through, keeping you invested in the bigger picture.

Character-Driven Growth: The focus isn’t solely on bombastic battles; the characters evolve and overcome personal struggles. Witness them grapple with self-doubt, discover hidden potential, and forge meaningful bonds that fuel their growth.

Themes Worth Exploring: This isn’t just about winning battles; it delves into themes of trust, cooperation, facing adversity, and finding your place in a complex world. These resonate deeply, making the journey more than just entertaining.

Be Patient, Reap the Rewards: Don’t be swayed by the initial slow burn. As you delve deeper, the strategic battles become more intense, the mysteries more gripping, and the character development emotionally rewarding. Trust the pacing, and you’ll be rewarded with a truly enriching experience.

Animation

World Trigger embraces a clean and dynamic art style, effectively portraying the intricate details of the characters and their environments. While not groundbreaking, the animation provides a clear and visually engaging experience.

Soundtrack and Music

World Trigger’s musical landscape skilfully complements the visual experience, amplifying the emotions and setting the stage for each encounter. Here’s a glimpse into what awaits:

  • Suspenseful Score: Prepare for a soundtrack that keeps you on the edge of your seat. Tense orchestral arrangements build anticipation during battles, while melancholic melodies delve into character moments.
  • Thematic Impact: Recurring motifs for specific characters or organizations create a sense of familiarity and deepen your connection to them.
  • Action-Packed Accompaniment: Witness intense clashes underscored by adrenaline-pumping music that heightens the impact of each strategic manoeuvre.
  • Quiet Contemplation: Moments of reflection and personal growth are accompanied by softer, introspective pieces, allowing you to connect with the characters’ emotional journeys.
  • Not Overpowering: While impactful, the music never overpowers the narrative, instead weaving seamlessly into the fabric of the story, enhancing the overall experience.

Good things

While strategic battles undoubtedly steal the show in World Trigger, its true strength lies in a multitude of captivating elements that elevate the entire experience. Here are some highlights:

1. Compelling Characters, Beyond Stereotypes:

Forget predictable archetypes; World Trigger boasts a diverse cast of individuals driven by unique motivations and facing personal hurdles. Witness them grow, forge unlikely bonds, and discover hidden strengths, making you genuinely invested in their journeys.

2. Intriguing World-Building:

The series goes beyond simply presenting an alien threat. Delve into a society built around a unique technology, explore the enigmatic Neighbors’ origins, and uncover the fascinating history of the Border organization. The world feels rich and complex, begging to be unravelled.

3. Tactical Genius on Display:

Move over, brute force! This is a celebration of strategic thinking and calculated manoeuvres. Witness characters analyse opponents, exploit weaknesses, and formulate intricate plans, making each battle a captivating intellectual puzzle.

4. A Masterful Blend of Genres:

World Trigger defies easy categorization. It effortlessly blends sci-fi elements with mystery, action, and even moments of humour, creating a refreshing and engaging experience that caters to diverse tastes.

5. More Than Just Fights:

While battles drive the narrative, the series explores meaningful themes like trust, cooperation, overcoming adversity, and finding your place in a complex world. These resonate deeply, adding emotional depth and leaving you with lasting reflections.

Bad things

Music Familiarity: While the soundtrack effectively sets the tone and underscores key moments, it might lack a distinct identity. Some viewers might find themselves noticing similarities to other anime scores, potentially leaving them wanting a more unique musical experience.

Pacing and Filler: While the deliberate world-building enriches the narrative, some episodes might feel stretched out. Frequent camera angle changes and extended scenes can slow down the pace, especially for viewers accustomed to faster-paced anime.

Character Similarities: Certain characters might evoke comparisons to archetypes or figures from other popular anime. This can sometimes lead to a feeling of “borrowing” rather than creating truly unique personalities.

Predictability: While some character actions and plot developments surprise, others might fall into predictable patterns. This can be a double-edged sword, offering comfort to some viewers while leaving others wanting more unexpected twists.

Conclusion

World Trigger isn’t just another anime; it’s a strategic masterpiece offering an experience that transcends thrilling battles and captivating mysteries. If you yearn for an anime that:

  • Blends complex tactics with a rich, immersive world
  • Features characters who evolve, forge bonds, and overcome personal struggles.
  • Celebrates strategic thinking and rewards patience with rewarding payoffs.
  • Delves into intriguing mysteries and explores meaningful themes.

Then look no further! While not without its minor drawbacks, World Trigger offers a unique and multifaceted experience that might just become your next favourite anime. So, step through the gate, embrace the slow burn, and prepare to be enthralled by a world where wit reigns supreme and alliances forge unexpected destinies. Will you answer the call and join the fight?

Selection Sort

Ever played “musical chairs” but with data elements? Selection Sort takes on this playful premise, ensuring each element finds its correct “chair” by repeatedly selecting the smallest and swapping it into place.

Process

Think of your data as a jumbled classroom. Selection Sort helps put everyone in their perfect seat, one by one. Here’s how:

  1. Pick a seat: Choose the first element as the “smallest” (or “largest”). It’s temporarily in its spot.
  2. Look around: Check everyone else (except the teacher’s pet in the front row, they’re already sorted!).
  3. Find the misplaced soul: If someone’s smaller (or larger) than the current “smallest,” remember their name! They’re the true contender.
  4. Switch desks: Swap the current “smallest” with the true contender. Now they’re both in the right place (sort of)!
  5. Repeat the process: Ignore the front row (sorted!), and start again from the next seat. Keep finding the truly smallest (or largest) and swapping them in.
  6. Class dismissed! Once everyone has switched seats the right number of times, the classroom (data) is perfectly sorted!

Pseudo Code

Code
function selectionSort(array):
  for i in range(len(array) - 1):
    min_index = i
    for j in range(i + 1, len(array)):
      if array[j] < array[min_index]:
        min_index = j
    swap(array[i], array[min_index])
  return array

function swap(a, b):
  temp = a
  a = b
  b = temp
Explanation
  1. The selectionSort function takes an array as input.
  2. for loop iterates through the array (except the last element, as it’s already in its final position).
  3. Inside the loop, a min_index variable is initialized to the current index (i). This assumes the element at this index is the smallest (or largest) so far.
  4. Another for loop iterates from the next element (i + 1) to the end of the array.
  5. If an element encountered in the inner loop is smaller (or larger) than the current min_index element, its index is stored in min_index. This new element becomes the candidate for the smallest (or largest).
  6. After the inner loop, the element at min_index is swapped with the element at the current index (i) using the swap function. This effectively places the smallest (or largest) element found so far in its correct position.
  7. The swap function takes two elements and exchanges their values.
  8. After all passes, the loop terminates, leaving the array sorted.

Implementations

Kotlin

Golang

Insertion Sort

Imagine organizing a messy bookshelf, placing each book where it belongs one by one. That’s the essence of Insertion Sort, inserting each data element into its correct position like finding the perfect spot for your favourite novel.

Process

Imagine you have a messy pile of playing cards and want to sort them in your hand, one by one. That’s the essence of Insertion Sort! Here’s how it works:

1. Start with one card: Consider the first element in your data as the sorted “hand.” It’s already in its rightful place.

2. Draw a new card: Look at the next element in the unsorted data (like drawing a new card).

3. Find the right spot: Compare the new card to each card in your sorted hand, starting from the “back” (highest/lowest depending on sorting order).

4. Make space: If you find a card bigger (or smaller) than the new one, shift all cards after it one position to the right (or left) to create a gap.

5. Insert the new card: Slide the new card into the empty space you just created, ensuring it’s now in its correct order within the sorted hand.

6. Repeat: Keep drawing new cards, comparing, shifting,

Pseudo Code

Code
function insertionSort(array):
  for i in range(1, len(array)):
    key = array[i]
    j = i - 1
    while j >= 0 and array[j] > key:
      array[j + 1] = array[j]  # Shift elements to create space
      j -= 1
    array[j + 1] = key  # Insert key in its correct position
  return array
Explanation
  1. The insertionSort function takes an array as input.
  2. for loop iterates through the array, starting from the second element (index 1), assuming the first element is already sorted.
  3. Inside the loop, the current element (key) is stored for comparison and potential insertion.
  4. Another while loop iterates backwards from the element before the key (j = i - 1), comparing elements with the key.
  5. If an element encountered in the inner loop is greater than the key, it’s shifted one position to the right to create space for the key.
  6. The inner loop continues shifting elements until a smaller element is found or the beginning of the array is reached.
  7. After the inner loop, the key is inserted into its correct position, ensuring sorted order up to that point.
  8. After all iterations, the array is sorted.

Implementations

Kotlin

Golang

Bubble Sort

Imagine sorting a messy pile of clothes, one swap at a time. That’s Bubble Sort in a nutshell! This simple algorithm might not be the speed king, but it’s a great way to understand sorting basics.

Process

Imagine you have a messy pile of toys and want to organize them by size. Bubble Sort does this by repeatedly comparing neighbouring toys:

  1. Start at the beginning: Compare the first two toys. If the second is bigger, swap their positions. This “bubbles” the larger toy towards the right.
  2. Repeat the comparison: Move one position to the right and compare the new pair. Swap if needed, again pushing the larger element further right.
  3. Keep going: Continue comparing and swapping pairs until you reach the end of the list. This completes one “pass.”
  4. Did we miss anything?: Repeat steps 1-3 from the beginning. With each pass, the largest element “bubbles” further right, leaving smaller ones sorted on the left.
  5. Are we done yet?: After a pass where no swaps occur, it means the list is sorted! You can celebrate with neatly organized toys (or data)!

Pseudo Code

Code
function bubbleSort(array):
  swapped = True
  while swapped:
    swapped = False
    for i in range(len(array) - 1):
      if array[i] > array[i + 1]:
        swap(array[i], array[i + 1])
        swapped = True
  return array

function swap(a, b):
  temp = a
  a = b
  b = temp
Explanation of code
  1. The bubbleSort function takes an array as input.
  2. swapped flag is initialized to True. This flag will be used to track if any swaps occurred during a pass.
  3. while loop continues as long as swapped is True. This means at least one swap occurred in the previous pass, and the list might not be fully sorted.
  4. Inside the loop, swapped is set to False at the beginning of each pass, assuming no swaps will occur.
  5. Another for loop iterates through the array (except the last element, as it’s already in its final position).
  6. If the current element is greater than the next element, they are swapped using the swap function. This “bubbles” the larger element towards the end of the list.
  7. If a swap occurs, the swapped flag is set to True to indicate that the list is not yet fully sorted.
  8. The swap function takes two elements and exchanges their values.
  9. After all passes, the loop terminates when swapped remains False, indicating the list is sorted.

Implementations

Kotlin

Golang

Unleashing Creativity: Preserving Knowledge, Projects, and Passions

Ever feel like your brilliant ideas and precious knowledge fade away over time? That’s what inspired me, Amrit Srivastava, a software engineer with a diverse skillset, to create this platform. Here, I’ll be showcasing my journey in backend engineering, Android development, and exploring innovative projects in fintech and agriculture. But this isn’t just about code; it’s about experiences, travels, and my evolving thoughts on various topics.

This website serves as a central hub for everything that ignites my passion. Whether you’re a fellow tech enthusiast, someone seeking unique perspectives, or simply curious about my adventures, you’ll find something valuable here. Dive into my past projects, explore practical training resources, wander through travelogues, and engage with my latest insights.