HiveBrain v1.2.0
Get Started
← Back to all entries
snippetgoMinor

Selection sort algorithm with increasing/decreasing sort options

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
selectiondecreasingwithoptionsalgorithmincreasingsort

Problem

I am running through some traditional algorithms in Go, and I was hoping to get feedback on efficiency and optimization.

Below is a basic selection sort algorithm that takes a parameter to dictate increasing, or decreasing order.

// SelectionSort
// in: A = {31, 41, 59, 26 , 41, 58}
//
// Increasing order
// out: A = {26, 31, 41, 41, 58, 59}

// Illustration:
// 31 | 41 | 59 | 26 | 41 | 58
// 31 | 41 | 59 | 26 | 41 | 58
// 31 | 41 | 59 | 26 | 41 | 58
// 26 | 31 | 41 | 59 | 41 | 58
// 26 | 31 | 41 | 41 | 59 | 58
//
// Decreasing order
// out: A = {59, 58, 41, 41, 31, 26}
//
// Illustration:
// 31 | 41 | 59 | 26 | 41 | 58
// 41 | 31 | 59 | 26 | 41 | 58
// 59 | 41 | 31 | 26 | 41 | 58
// 59 | 41 | 31 | 26 | 41 | 58
// 59 | 41 | 41 | 31 | 26 | 58
// 59 | 58 | 41 | 41 | 31 | 26
package main

import (
    "fmt"
)

// Function that performs a selection sort.
// Second parameter specifies increasing or decreasing order.
func SelectionSort(A []int, S string) []int {
    for i := range A {
        for j := i + 1; j  A[j] {
                    A[i], A[j] = A[j], A[i]
                }
            case S == "decreasing":
                if A[i] < A[j] {
                    A[i], A[j] = A[j], A[i]
                }
            }
        }
    }
    return A
}

func main() {
    A := []int{31, 41, 59, 26, 41, 58}
    fmt.Println("Unsorted array: ", A)
    fmt.Println("Increasing sort array: ", SelectionSort(A, "increasing"))
    fmt.Println("Decreasing sort array: ", SelectionSort(A, "decreasing"))
}

Solution

There are a few things I would point out as being poor go style. The two different nesting loops is where I would start:

for i := range A {
    for j := i + 1; j < len(A); j++ {


The outer loop does a index-only range on the A slice, which in itself is not a problem, but logically it is for i := 0; i < len(A); i++ {. Again, this is not really a problem, other than the fact that you are looping the indexes of the slice. The problem is that in your inner loop, you make that index-loop obvious with the full-syntax loop.

I would be tempted to use a full loop for the outer loop so that the index functions on i and j are obvious.

The other thing I would suggest is that you supply a function for the S parameter, instead of a string.

While mentioning parameters, it is not common practice to use upper-case parameter names. These parameters are never exported, so should be lower-case initial, and mixedCase for multi-word names.

If you supply a function for the sort order, then your sort function is improved as well. Consider:

func SelectionSort(data []int, ordered func(int, int) bool) []int {
    for i := 0; i < len(data); i++ {
        for j := i + 1; j < len(data); j++ {
            if !ordered(data[i], data[j]) {
                data[i], data[j] = data[j], data[i]
            }
        }
    }
    return data
}


Now, you can call that code with something like:

increasing := func(a, b int) bool {
    return a  b
}

data := []int{31, 41, 59, 26, 41, 58}
fmt.Println("Increasing sort array: ", SelectionSort(data, increasing))
....

Code Snippets

for i := range A {
    for j := i + 1; j < len(A); j++ {
func SelectionSort(data []int, ordered func(int, int) bool) []int {
    for i := 0; i < len(data); i++ {
        for j := i + 1; j < len(data); j++ {
            if !ordered(data[i], data[j]) {
                data[i], data[j] = data[j], data[i]
            }
        }
    }
    return data
}
increasing := func(a, b int) bool {
    return a <= b
}

decreasing := func(a, b int) bool {
    return a > b
}

data := []int{31, 41, 59, 26, 41, 58}
fmt.Println("Increasing sort array: ", SelectionSort(data, increasing))
....

Context

StackExchange Code Review Q#117083, answer score: 6

Revisions (0)

No revisions yet.