Search code examples
algorithmsortingselection-sort

Modification to Selection Sort. Theoretically seems correct but doesn't give the results


I am learning ruby and the way I am going about this is by learning and implementing sort algorithms. While working on selection sort, I tried to modify it as follows:

  • In every pass, instead of finding the smallest and moving it to the top or beginning of the array, find the smallest and the largest and move them to both ends

  • For every pass, increment the beginning and decrease the ending positions of the array that has to be looped through

  • While swapping, if the identified min and max are in positions that get swapped with each other, do the swap once (otherwise, two swaps will be done, 1 for the min and 1 for the max)

This doesn't seem to work in all cases. Am I missing something in the logic? If the logic is correct, I will revisit my implementation but for now I haven't been able to figure out what is wrong.

Please help.

Update: This is my code for the method doing this sort:

def mss(array)
  start = 0;
  stop = array.length - 1;
  num_of_pass = 0
  num_of_swap = 0
  while (start <= stop) do
    num_of_pass += 1
    min_val = array[start]
    max_val = array[stop]
    min_pos = start
    max_pos = stop
    (start..stop).each do
      |i|
      if (min_val > array[i])
        min_pos = i
        min_val = array[i]
      end
      if (max_val < array[i])
        max_pos = i
        max_val = array[i]
      end
    end
    if (min_pos > start)
      array[start], array[min_pos] = array[min_pos], array[start]
      num_of_swap += 1
    end
    if ((max_pos < stop) && (max_pos != start))
      array[stop], array[max_pos] = array[max_pos], array[stop]
      num_of_swap += 1
    end
    start += 1
    stop -= 1
  end
  puts "length of array = #{array.length}"
  puts "Number of passes = #{num_of_pass}"
  puts "Number of swaps = #{num_of_swap}"
  return array
end

Solution

  • The problem can be demonstrated with this input array

    7 5 4 2 6
    

    After searching the array the first time, we have

    start   = 0
    stop    = 4
    min_pos = 3
    min_val = 2
    max_pos = 0    note: max_pos == start
    max_val = 7
    

    The first if statement will swap the 2 and 7, changing the array to

    2 5 4 7 6
    

    The second if statement does not move the 7 because max_pos == start. As a result, the 6 stays at the end of the array, which is not what you want.