I'm trying out Scala and I want to see how one would implement insertion sort in scala with the following requirements:
- Nested for loops
- Array[Int] for input
- If possible a way to modify the contents of the function in a call by reference way otherwise return an Array[Int]
If this isn't the Scala way of implementing insertion sort can you still provide code for the above and explain what is wrong with the approach. edit: This is an attempt using a while loop (doest work) and no it isn't a homework question, why the hostility?
def insert_sort(a:Array[Int]):Array[Int]={
for(i <- 0 until a.length)
{
var j=i+1
while(j>1&&a(j)<a(j-1)&&j<a.length)
{
var c=a(j)
a(j)=a(j-1)
a(j-1)=c
j-=1
}
}
return a
}
Nested for loops are probably not the answer in Scala, whatever is the problem. They make sense in languages where for loops stand for "repeat until condition, changing this each iteration", which is not what for loops or for comprehensions are in Scala (a for comprehension is a for loop which yields something for each iteration).
In Scala, for loops and for comprehensions are iterations over the elements of a collection (or weirder things for non-collection monads), but for insertion sort you want to find a position, either swapping places up to that position, or inserting the element at that position. Finding stuff should not be done with for loops or for comprehensions.
Also, there's no pass-by-reference in Scala. And, in fact,
Array
is not even a Scala collection, but a Java thingy which has unique characteristics granted to it by the JVM that are not reproducible with classes, so it can't be replaced.My version of the insertion sort procedure is the following. It consists of two functions,
isort
andinsert
which have the following signatures:isort(xs: List[int]) : List[int]
: Takes an input list of integers and outputs a list of integers.insert(x: Int, xs: List[int]) : List[int]
Takes a sorted input list and an integerx
and addsx
to the right position in the list to maintain the invariant that the list is sorted. Example:insert(3, [1, 2]) = [1, 2, 3]
First let us code up the
insert
function.Otherwise, there are two possible cases. The head of the list is greater or equal to the given input integer, in which case we simply append the input integer to the beginning of the list and return it. The other case is when the input integer is greater than the head of the input list. In this case, we recursively insert the input integer into the tail of the list.
The second function is
isort
, which takes an input list and sorts it. The algorithm is as follows:Nil
, returnNil
.Otherwise, recursively sort the tail of the list, and add the head at the right position in the (sorted) tail (using the
insert
procedure)We can test this as
isort(List(1, 6, 4, -2, 5, 12))
and we get the correct expected output.Here is a code sample written using foldLeft.
The example can be found in this github repo.
This is what I came up with, which seems to be functional, generic, tail-recursive (
foldLeft
is tail-recursive)...:here's another generic version of insertion sort:
The most elegant insertion sort algorithm implementation that I'we seen so far:
Algorithm implementation is taken from this great book: https://www.artima.com/shop/programming_in_scala_3ed