Welcome Gophers! In this lesson, we are going to implement the bubble sorting algorithm that we covered in the last lesson.
Implementation
Let’s start off by creating a new file called main.go within a new directory called 01-bubble-sort/. I’ll be segregating each sorting and searching algorithm into a separate named directory under the one repository just for ease.
Let’s start by creating a simple main function that prints out something.
package main
import "fmt"
func main() {
fmt.Println("Bubble Sorting Algorithm in Go")
}
Now, let’s start off by defining the function signature for our bubble sort function.
// BubbleSort - takes in a slice of ints and returns a sorted slice of ints
func BubbleSort(input []int) []int {
}
We want this function to take in a slice of integers and then return another slice which has been sorted.
Now, let’s take a stab at filling out this new BubbleSort function. We want to start by defining n which will be equal to the length of our slice of ints. We also want to declare a new swapped bool and initialize this to true:
func BubbleSort(input []int) []int {
n := len(input)
swapped := true
}
Next, we want to create a for loop that is going to contain the logic for comparing each element in the array:
for swapped {
// set swapped to false
swapped = false
// iterate through all of the elements in our list
for i := 0; i < n-1; i++ {
// if the current element is greater than the next
// element, swap them
if input[i] > input[i+1] {
// log that we are swapping values for posterity
fmt.Println("Swapping")
// swap values using Go's tuple assignment
input[i], input[i+1] = input[i+1], input[i]
// set swapped to true - this is important
// if the loop ends and swapped is still equal
// to false, our algorithm will assume the list is
// fully sorted.
swapped = true
}
}
}
Awesome, at this point, we should have a fully functional implementation of our Bubble Sort algorithm! Let’s test it out by creating a slice within our main function and then calling our new BubbleSort function:
func main() {
fmt.Println("Bubble Sorting Algorithm in Go")
unsortedInput := []int{5,3,4,1,2}
sorted := BubbleSort(unsortedInput)
fmt.Println(sorted)
}
Perfect, let’s give this a shot and try and run it from the command line:
$ go run main.go
Bubble Sorting Algorithm in Go
Swapping
Swapping
Swapping
Swapping
Swapping
Swapping
Swapping
Swapping
[1 2 3 4 5]
Perfect, we now have a sorted slice of ints and we’ve also got the number of times a swap has been performed through counting the number of times Swapping has been printed out.
Writing Proper Tests
Let’s add a test file main_test.go to make sure our implementation handles a few different cases:
package main
import (
"reflect"
"testing"
)
func TestBubbleSort(t *testing.T) {
tests := []struct {
name string
input []int
expected []int
}{
{"basic", []int{5, 3, 4, 1, 2}, []int{1, 2, 3, 4, 5}},
{"already sorted", []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}},
{"reverse sorted", []int{5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5}},
{"single element", []int{42}, []int{42}},
{"empty", []int{}, []int{}},
{"duplicates", []int{3, 1, 3, 2, 1}, []int{1, 1, 2, 3, 3}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := BubbleSort(tt.input)
if !reflect.DeepEqual(result, tt.expected) {
t.Errorf("got %v, want %v", result, tt.expected)
}
})
}
}
$ go test -v
=== RUN TestBubbleSort
=== RUN TestBubbleSort/basic
=== RUN TestBubbleSort/already_sorted
=== RUN TestBubbleSort/reverse_sorted
=== RUN TestBubbleSort/single_element
=== RUN TestBubbleSort/empty
=== RUN TestBubbleSort/duplicates
--- PASS: TestBubbleSort (0.00s)
PASS
All passing — nice.
Conclusion
We now have a working Bubble Sort implementation in Go. The key takeaway is the swapped flag — once a full pass completes with no swaps, we know the array is sorted and can bail out early. It’s not the fastest algorithm out there, but it’s a great one to start with because the logic is straightforward.
In the next lesson, we’ll look at Insertion Sort, which takes a slightly different approach.
