Understanding Selection Sort with Ruby

honeybadger_staff

Honeybadger Staff

Posted on August 25, 2020

Understanding Selection Sort with Ruby

This article was originally written by Julie Kent on the Honeybadger Developer Blog.

In this post, I'll be walking through how to implement a selection sort algorithm with Ruby. Selection sort is an in-place comparison sorting algorithm. This means that sorted items occupy the same storage as the original ones. Before we go any further, it's important to note that the selection sorting algorithm is not commonly used in practice unless the dataset is small (i.e., 10-20 elements). However, it's a great starter algorithm to learn and understand, similar to learning how to ride a tricycle before a bicycle, if you will. The implementation might show up on a coding challenge for a job interview, or you might be asked to explain why an algorithm like selection sort would not be very practical on a large dataset. Selection sort does usually outperform bubble sort, which is the first algorithm we looked at in this series.

At a high level, selection sort divides the array into two parts: one half sorted and the other not. At the onset, the sorted section is empty, and the unsorted portion contains all of the elements. Selection sort utilizes two loops; the outer loop iterates n times, where n is the number of elements in the array. We immediately set the "min index" to the first element, and then use another loop to compare elements, swapping the min index if the adjacent element is less than the current minimum.

If this is hard to follow, don't worry! We're going to walk through an actual example next. :)

Step By Step

Let's start with an array with the following elements: [10, 30, 27, 7, 33, 15, 40, 50]

Iteration one: Find the smallest number

In this case, the smallest number is 7, so we place it at the beginning and move 10 to where the 7 was. Our array now looks like this: [7, 30, 27, 10, 33, 15, 40, 50]

Iteration two: Find the next smallest number

Starting at the element in index position 1 (remember, arrays are 0-indexed), find the next smallest element

In this case, it is 10. Move 10 to the second position in the array and move 30 to where the 10 was. The resulting array is this: [7, 10, 27, 30, 33, 15, 40, 50]

From here, we continue this exact process until our array is fully sorted. Below, you can see the resulting arrays after the next iterations.

Iteration three:

[7, 10, 15, 30, 33, 27, 40, 50]

Iteration four:

[7, 10, 15, 27, 33, 30, 40, 50]

Iteration five:

[7, 10, 15, 27, 30, 33, 40, 50]

Bingo! We are sorted!

If you're more a visual learner, here is an example of how a selection sort would work with an array of []

Selection sort visually
Photo credit

A Ruby Implementation

Here is a selection sort function written in Ruby:

def selection_sort(array)
  n = array.length - 1
  n.times do |i|
    min_index = i
    for j in (i + 1)..n
      min_index = j if array[j] < array[min_index]
    end
    array[i], array[min_index] = array[min_index], array[i] if min_index != i
  end
  puts array
end
Enter fullscreen mode Exit fullscreen mode

Let's look at how this works.

First, we set n equal to the number of elements. Remember, we need to subtract one because arrays are 0-indexed.

Next, we create our outer loop, which is going to run n times.

min_index = i
Enter fullscreen mode Exit fullscreen mode

Here, we are setting the minimum index to the element in the first position.

for j in (i + 1)..n
Enter fullscreen mode Exit fullscreen mode

Next, we create our inner loop. This line is saying "for the element in the second position to the nth element, do what follows". If you aren't familiar with the .. operator, it creates a range from the start point to the endpoint, inclusively. For example, 1..10 creates a range from 1 to 10, inclusive.

min_index = j if array[j] < array[min_index]
Enter fullscreen mode Exit fullscreen mode

Inside this loop, we set the min_index to a new element if it less than the current min_index.

array[i], array[min_index] = array[min_index], array[i] if min_index != i
Enter fullscreen mode Exit fullscreen mode

Outside of our inner loop, we look to see if the current min_index is equal to i. If this is true, we need to shuffle our elements. We set array[i] to array[min_index] and array[min_index] to array[i]. Here, we are performing the "swap" the same as we did in our example.

Finally, once we are finished, we output our array, which is now sorted!

Putting it All Together

Here is my full program:

def selection_sort(array)
  n = array.length - 1
  n.times do |i|
    min_index = i
    for j in (i + 1)..n
      min_index = j if array[j] < array[min_index]
    end
    array[i], array[min_index] = array[min_index], array[i] if min_index != i
  end
  puts array
end

array = [10, 30, 27, 7, 33, 15, 40, 50]

selection_sort(array)
Enter fullscreen mode Exit fullscreen mode

Running ruby ruby-selection-sort.rb from the terminal outputs the following:

7
10
15
27
30
33
40
50
Enter fullscreen mode Exit fullscreen mode

Cool!

Understanding Why Selection Sort is Inefficient

One way to measure an algorithm's efficiency is to look at the "Big-O notation"; this represents the worst-case performance so that algorithms can be compared. For example, an algorithm with a Big-O of O(1) means that the worst-case run time is constant as the number of elements, "n", grows, whereas an algorithm with a Big-O notation of O(n) means that the worst-case run time increases linearly as n grows. This means that if you have an array with 100 elements and must choose between sorting algorithms that are O(n) and O(1), you would choose the O(1) algorithm because O(1) definitely beats O(100).

Like the bubble sort, the selection sort has a worst-case and average complexity of O(n^2) because of the nested loops. This means that its efficiency decreases dramatically as the number of elements grows.

Wrapping Up

All things considered, selection sort is still an interesting algorithm that may pop-up in a coding challenge. Or, you may be given a selection sort function and asked what the Big-O notation is and why. Hopefully, the examples in this article will help you be ready to tackle either scenario.

💖 💪 🙅 🚩
honeybadger_staff
Honeybadger Staff

Posted on August 25, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related