You are on page 1of 18

Data

Structures and Algorithms in Go

Table of Contents
Introduction 0
Minimum Viable Go 1
Arrays 2

2
Data Structures and Algorithms in Go

Data Structures and Algorithms in Go


Written by Bill Broughton

This book is just getting started and doesn't have much content yet. Stay tuned.

Learning data structures and algorithms is the next step in improving programming skills.
Sound knowledge of data structures and algorithms will allow you to solve new problems,
develop more performant applications, and discover new design paradigms.

The learning of data structures and algorithms also happens to be a good vessel for learning
key elements of a programming language. That is the key focus of this book. You will learn
the Go programming language in conjunction with the concepts presented in the book.

This book is focused on practical application and will only delve into theoretical foundations
as needed to understand the application.

Who this book is for


This book is best for individuals with some experience in at least one programming
language. The basics of the Go programming language will be covered, but the presentation
is terse and not all explanations will be easily understood by beginning programmers.

There are problem sets presented at the end of each chapter, however solutions will be
publicly available online. This point would exclude the text from being used for formal
instruction purposes unless an instructor developed their own problem sets.

Example code
All code presented in this book is available on GitHub.

Note on computational complexity


Nearly all Data Structures and Algorithms books cover computational complexity at some
level of detail. This book does not follow that pattern. Many resources already exist online for
learning computational complexity concepts. This book references the complexity of
operations, but does not attempt to teach the concepts.

Introduction 3
Data Structures and Algorithms in Go

Technical requirements
The technical requirements to follow this book are simple:

Go language installed on your computer


A text editor

If you are looking for a solid, free text editor with Go language support, I would recommend
looking at GitHub Atom.

Where to find it
Read Online At:

https://www.gitbook.com/book/wlbrough/data-structures-and-algorithms-in-go

Download a .pdf, .epub, or .mobi File From:

https://www.gitbook.com/book/wlbrough/data-structures-and-algorithms-in-go/details

Contribute Content, Suggestions, and Fixes on GitHub:

https://github.com/wlbrough/data-structures-and-algorithms-in-go

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0


Unported License.

Introduction 4
Data Structures and Algorithms in Go

Minimum Viable Go
Go is an open source programming language that makes it easy to build simple,
reliable, and efficient software.

golang.org

A team at Google developed Go in 2007 and the language was released publicly in 2009.
The language was originally developed as a systems programming language and has
syntactic similarity to C-derived languages. While taking some syntax from C, Go also
adopted conventions from dynamic languages to make the code easier to read and
understand. Simplicity was a stated goal of the project. Go features built in concurrency, a
native package manager, and an extensive standard library.

This chapter covers the basics of the language to get started with the material. New pieces
of the programming language are introduced as they are needed throughout the text.

Getting set up
Find the instructions to install and configure Go on the official Go website.

I will point out that you should ensure that you have set your GOPATH environment variable
is set to your working directory.

As stated in the introduction, I recommend GitHub's Atom text editor if you do not already
have a preferred text editor.

Other resources
If you are looking for a guided tutorial or more detailed documentation, you can find it on the
Go documentation page. In particular, check out the following resources:

A Tour of Go <- Guided tutorial


How to write Go code <- Quick guidance on building packages, testing, etc.
Effective Go <- Guidance on writing idiomatic code and language details

Go Tool
Once you have Go installed, you can verify the installation by typing:

Minimum Viable Go 5
Data Structures and Algorithms in Go

go version

The current version is 1.6 at the time I an writing this. You will see a result like the following:

go version go1.6 linux/amd64

In addition to the compiler, Go installs a suite of tools under the go command. You can see
the full listing of commands by running go help .

Types and data structures


Primitive data types and data structures are the basic building blocks in any programming
language. Go has a simple - but flexible - type system. Go is statically typed, so once a
variable is declared its type cannot be changed.

Primitives
Go has integer and floating point number types, a string type, and a boolean type. The
number types can be declared with a memory allocation, but it is generally easier to let Go
manage the memory allocation.

Integers
Integers are numbers without a decimal component or "round numbers". Go integers can be
unsigned (i.e. positive only) like uint8 , uint16 , uint32 , or uint64 or signed (positive or
negative) like int8 , int16 , int32 , int64 . The numbers in those type declarations
represent the number of bits allocated for the number.

For simplicity, Go has integer types that are allocated based on machine architecture: int ,
uint , and uintptr . int and uint will be either 32 or 64 bits depending on architecture.

uintptr is an integer pointer.

For the purposes of this book, integers will always be declared as int .

Example:

Minimum Viable Go 6
Data Structures and Algorithms in Go

package main

import "fmt"

func main() {
var one int = 1
var two int = 2
fmt.Println("1 + 2 =", one + two)
}

Floating point numbers


Floating point numbers are numbers with a decimal component. Floating point numbers are
inexact which can cause strange errors when using comparison operators in your programs.

Go has two floating point types: float32 and float64 . Unless there are memory concerns,
float64 is generally used. Go also has types for complex numbers complex64 and

complex128 which are composed of two float32 s or two float64 s respectively.

Example:

package main

import "fmt"

func main() {
var seven float64 = 7.
var twoandahalf float64 = 2.5
fmt.Println("7 / 2.5 =", seven / twoandahalf)
}

Strings
Strings are composed of letters and numbers and have the type string . They can be
defined using double quotes "Go is awesome!" or backticks Go is awesome! . Strings
created with double quotes allow the use of escape characters like \n and \t , while
strings created with backticks allow newlines.

Booleans
Booleans are either true or false and have the type bool . There are three logical operators
used with booleans:

&& for and

|| for or

Minimum Viable Go 7
Data Structures and Algorithms in Go

! for not

Example:

package main

import "fmt"

func main() {
var isTrue bool = true
fmt.Println("isTrue is", isTrue)
}

Arrays
Go arrays have a fixed size and a single type. Like most other programming languages,
arrays are zero indexed. A new array variable is defined like this:

var arr [10]string

This creates an array with 10 string elements. An array can also be initialized with an array
literal:

var arr [5]int{ 1, 2, 3, 4, 5 }

Arrays are fixed in size, so trying to add a sixth element to the previously defined int array
will cause an error:

arr[5] = 6 //Causes an error at compile time

Slices
A slice can be thought of as a dynamic array. Slices have elements of a single type like
arrays, but can grow to accommodate new elements. Slices are defined like this:

var x []int

This creates a 0 length slice that accepts int elements. To initialize the slice with a length,
but defining no elements, the make function is used:

var x = make([]int, 5)

Minimum Viable Go 8
Data Structures and Algorithms in Go

Slices can also take elements from an array segment:

var arr = [5]int{ 1, 2, 3, 4, 5 }


x := arr[2:5] // x == [3, 4, 5]

Maps
A map is an unordered key-value collection. In other languages this is called an associative
array, hash, or dictionary. Maps are declared with the key type and the value type:

var x map[string]float64

The map x has string -type keys and float64 -type values. For example x["apple"] =
0.99 .

One caveat is that maps must be initialized before they are used, so in practice the above
example will be declared as:

x := make(map[string]float64)

Variables
The section on types and data structues presented two ways to declare a variable: the var
keyword and the := operator. With the var keyword, you must declare the type for the
variable. The := operator infers the type based on the value provided, but the type remains
fixed after declaration. For example, the following variable declations are equivalent:

var x int = 7
x := 7

Variable naming
Variable names in go must start with a letter and can contain letters, numbers, and the _
underscore character. In practice, multi-word variable names should be camelCased rather
than snake_cased . Names should be terse, but descriptive.

Variable scope

Minimum Viable Go 9
Data Structures and Algorithms in Go

According to the Go docs "Go is lexically scoped using blocks". This means that variables
declared inside a set of curly braces ( { } ) cannot be accessed outside of that block. For
example:

package main

import "fmt"

func other() {
var x int = 5
fmt.Println("x =", x)
}

func main() {
x := 8
fmt.Println("x =", x)
other()
}

If you run this program, the output will be:

8
5

if and for blocks also have their own scope, so variables defined in those blocks will be

limited to use inside that block.

Constants
Constants are immutable variables that are defined with the const keyword:

const message string = "All hail Flying Spaghetti Monster!"


message = "Hello world!" // Throws compile error

Control structures
A major difference you will notice coming from most other languages is that Go does not use
parenthesis around the conditions for control structures. You will see this in practice as each
control structure is discussed, but it is important to know that this is not an omission.

if
if takes a condition and runs the code in the block if the condition is true. For example:

Minimum Viable Go 10
Data Structures and Algorithms in Go

x := 5
if x == 5 {
fmt.Println("x is 5")
}

If there is also code that should run in the case that the condition is not true, the else
keyword is used. Modifying the previous example:

if x == 5 {
fmt.Println("x is 5")
} else {
fmt.Println("x is not 5")
}

If there are more conditions that need to be handled, the else if part can be added:

if x == 5 {
fmt.Println("x is 5")
} else if x == 10 {
fmt.Println("x is 10")
} else {
fmt.Println("x is not 5 or 10")
}

switch
If there are several else if statements in your if block, it may be more efficient to use
the switch statement. To rewrite the last example in the if section:

switch x {
case 5: fmt.Println("x is 5")
case 10: fmt.Println("x is 10")
default: fmt.Println("x is not 5 or 10")
}

Unlike some other languages, Go switch statements do not "fall through". If a case is
matched, the switch statement breaks and the next statement following the switch is
executed. This is why there is no break statement needed after each case.

for
for is the only looping structure in Go. There is no while or do...while . These

operations are supported using the for keyword.

Minimum Viable Go 11
Data Structures and Algorithms in Go

for can be declared as an infinite loop:

for {
// ever and ever
break // just kidding
}

for can also be used like a while in other languages:

x := 10
for x > 0 {
// do something
x--
}

Finally, for can be used in the classical for structure:

for x := 0; x < 10; x++ {


// do something
}

Functions
Functions are declared with the format func name(arguments) T { ... } . To tie together
previous concepts and present function composition, an example will be followed with
explanation.

package main

import "fmt"

func sum(x []int) int {


total := 0
for _, v := range x {
total += v
}
return total
}

func main() {
var nums []int{5, 6, 7, 8}
fmt.Println(sum(nums)) // Prints 26
}

Minimum Viable Go 12
Data Structures and Algorithms in Go

The function sum takes one argument: a slice containing integers that will be called x
within the function block. The int between the closing parenthesis and the opening curly
bracket ) int { is the return type. This means that the function will send back an integer
when it is finished processing.

The syntax in the for condition is unfamiliar. The range function returns an index and a
value for each element in an array, slice, or map. The underscore _ receives the index, but
allows the program to ignore it because it is unused. If a named variable was declared and
not used, it would cause a compile error.

Returning multiple values


Functions in go can return multiple values. To receive multiple values, the return type is
changed to a comma separated list of types and the := is used in the assignment
statement.

func multVal() (int, int) {


return 5, 9
}

func main() {
x, y := multVal()
}

Structs
A struct defines a data object type with a specified collection of fields. Go does not have
classes and does not have a class keyword, but structs are roughly analogous. Methods
are associated to structs rather than being composed within the struct.

As an example, a struct for a person could be defined as:

type Person struct {


firstName string
lastName string
age integer
eyeColor string
glasses bool
}

Initialization

Minimum Viable Go 13
Data Structures and Algorithms in Go

There are many ways to create a new instance of the struct. To define the local variable,
use:

var me Person

The alternative form initializes all fields to their zero-value, allocates memory, and returns a
pointer:

me := new(Person)

To define the value for each field at initialization, use this format:

me:= Person{firstName: "Bill", lastName: "Broughton", age: 29, eyeColor: "Brown", glasses:

If the order of the fields is known, the field names can be left out:

me:= Person{"Bill", "Broughton", 29, "Brown", true}

Fields
Fields are accessed through dot notation.

fmt.Println(me.firstName, me.lastName) // Output: "Bill Broughton"


me.lastName = "Smith"
fmt.Println(me.firstName, me.lastName) // Output: "Bill Smith"

Keep in mind that function arguments are always copied in Go, so functions will not change
field values unless the instance is passed as a pointer.

// Arguments copied
func incrementAge(p Person) integer {
p.age++
return p.age
}

me:= Person{"Bill", "Broughton", 29, "Brown", true}


fmt.Println(incrementAge(me)) // Output: 30
fmt.Println(me.age) // Output: 29

Minimum Viable Go 14
Data Structures and Algorithms in Go

// Arguments copied
func incrementAge(p *Person) integer {
p.age++
return p.age
}

me:= Person{"Bill", "Broughton", 29, "Brown", true}


fmt.Println(incrementAge(&me)) // Output: 30
fmt.Println(me.age) // Output: 30

Methods
The example above presents a simple use case for a method. Methods are associated with
structs rather than composed in the struct. Modifying the function above:

func (p *Person) incrementAge() integer {


p.age++
return p.age
}

me:= Person{"Bill", "Broughton", 29, "Brown", true}


fmt.Println(me.incrementAge()) // Output: 30
fmt.Println(me.age) // Output: 30

The method name is defined between the arguments and the return type. Defining a method
like this associates it with the Person struct and allows the use of the dot notation. Here's
another example for an introduction:

func (p *Person) introduce() string {


fmt.Println("Hi my name is", p.firstName)
}

me:= Person{"Bill", "Broughton", 29, "Brown", true}


me.introduce() // Output: "Hi my name is Bill"

Type embedding
Rather than classical inheritance, Go uses embedded types. To demonstrate this concept,
we define an Author struct that embeds the Person type discussed in the prior section.

Minimum Viable Go 15
Data Structures and Algorithms in Go

type Author struct {


Person
publishedBooks []string
}

me := Author{
Person: Person{
firstName: "Bill",
lastName: "Broughton",
age: 29,
eyeColor: "Brown",
glasses: true
},
publishedBooks: make([]string,1)
}

// Now properties and methods from Person can be used with Author
me.incrementAge()
fmt.Println(me.age) // Output: 30

The final word


This is a brief introduction to the Go programming language, but it has covered most of the
critical concepts to get started. Additional concepts will be introduced on an as needed basis
throughtout the rest of the text.

Minimum Viable Go 16
Data Structures and Algorithms in Go

Arrays
To explore the functionality of the array data structure, a new MyArray struct will be
implemented with methods that duplicate the functionality of Go's built-in arrays. The built-in
Array type will be used for data storage only.

This chapter works with basic arrays, dynamic arrays, and ordered arrays. Linear search
and binary search are also discussed.

Basic array
The basic array is a fixed-length sequence of elements of a single type.

TODO: Add a description and some background. NOTE: Discussion of duplicates in the
array.

Insert element at end of array


TODO: Write content

Show value at index


TODO: Write content

Delete element by index


TODO: Write content

Display array
TODO: Write content

Insert element at index


TODO: Write content

Linear search
TODO: Write content

Arrays 17
Data Structures and Algorithms in Go

Delete element by value


TODO: Write content

Dynamic array
TODO: Add a description and some background.

Modifying insert methods


TODO: Write content

Modifying delete methods


TODO: Write content

Ordered array
TODO: Add a description and some background.

Binary search
TODO: Write content

Insert element in order


TODO: Write content

Exercises
1. Implement findMin & findMax methods (TODO: add detail)
2. Implement deleteMin & deleteMax methods (TODO: add detail)
3. Implement getAvg method (TODO: add detail)
4. Implement reverseOrder method (TODO: add detail)
5. Use binary search for insert and delete methods in the ordered array (TODO: add
detail)
6. Implement a merge method (TODO: add detail)

Arrays 18

You might also like