Skip to content

Instantly share code, notes, and snippets.

@grevych
Last active July 17, 2019 22:48
Show Gist options
  • Save grevych/d601479ed71603bb6807c2c8c019e9b1 to your computer and use it in GitHub Desktop.
Save grevych/d601479ed71603bb6807c2c8c019e9b1 to your computer and use it in GitHub Desktop.
Linked list of integers https://goplay.space/#jOlr7VSOmrK
package main
import (
"errors"
"fmt"
)
type node struct {
value int
next *node
}
type list struct {
length int
head *node
tail *node
}
type List interface {
Print()
Length() int
IndexOf(value int) int
Append(value int)
Insert(value, position int) error
Remove(position int) error
}
var _ List = &list{}
func NewList() List {
return &list{}
}
func newNode(value int) *node {
return &node{value, nil}
}
func (l *list) insertFirst(value int) error {
if l.head == nil {
return errors.New("Head list cannot be nil")
}
node := newNode(value)
node.next = l.head
l.head = node
l.length += 1
return nil
}
func (l *list) insertBetween(value, position int) error {
current := l.head
for index := 0; index < position-1; index++ {
if current == nil {
return errors.New("Position does not exist")
}
current = current.next
}
node := newNode(value)
node.next = current.next
current.next = node
l.length += 1
return nil
}
func (l *list) insertLast(value int) error {
if l.tail == nil {
return errors.New("Tail list cannot be nil")
}
node := newNode(value)
l.tail.next = node
l.tail = node
l.length += 1
return nil
}
func (l *list) removeFirst() error {
if l.head == nil {
return errors.New("Head list cannot be nil")
}
l.head = l.head.next
l.length -= 1
return nil
}
func (l *list) removeBetween(position int) error {
current := l.head
for index := 0; index < position-1; index++ {
if current == nil {
return errors.New("Position does not exist")
}
current = current.next
}
current.next = current.next.next
l.length -= 1
return nil
}
func (l *list) removeLast() error {
if l.head == nil {
return errors.New("Head list cannot be nil")
}
if l.tail == nil {
return errors.New("Tail list cannot be nil")
}
current := l.head
for ; current.next != l.tail; current = current.next {
}
current.next = nil
l.length -= 1
return nil
}
func (l *list) Append(value int) {
_ = l.Insert(value, l.length)
}
func (l *list) Insert(value, position int) error {
if position > l.length {
return errors.New("Position is greater than length")
}
if position < 0 {
return errors.New("Position is lower than 0")
}
if l.head == nil && l.tail == nil {
node := newNode(value)
l.head = node
l.tail = node
l.length += 1
return nil
}
if position == 0 {
return l.insertFirst(value)
}
if position == l.length {
return l.insertLast(value)
}
return l.insertBetween(value, position)
}
func (l *list) Remove(position int) error {
if l.length == 0 {
return errors.New("Empty list")
}
if l.length < position {
return errors.New("Position is greater than length")
}
if l.head == l.tail {
l.head = nil
l.tail = nil
l.length -= 1
return nil
}
if position == 0 {
return l.removeFirst()
}
if position == l.length {
return l.removeLast()
}
return l.removeBetween(position)
}
// Search looks for the given number in the list and returns the
// position in case it exists. Otherwise, returns -1
func (l *list) IndexOf(value int) int {
index := 0
for current := l.head; current != nil; current = current.next {
if current.value == value {
return index
}
index += 1
}
return -1
}
func (l *list) Print() {
for current := l.head; current != nil; current = current.next {
fmt.Printf("%d ", current.value)
}
fmt.Println()
}
// Length returns the length of the list
func (l *list) Length() int {
return l.length
}
func main() {
list := NewList()
list.Append(11)
list.Print()
list.Append(12)
list.Print()
list.Append(13)
list.Print()
list = NewList()
// Insert in empty list
err := list.Insert(11, 0)
fmt.Println(err)
list.Print()
// Insert in inexistent position
err = list.Insert(11, 2)
fmt.Println(err)
list.Print()
// Insert at the end
err = list.Insert(13, 1)
fmt.Println(err)
list.Print()
// Insert in between
err = list.Insert(12, 1)
fmt.Println(err)
list.Print()
// Insert at the begining
err = list.Insert(10, 0)
fmt.Println(err)
list.Print()
// IndexOf
fmt.Println(list.IndexOf(11))
// Remove first
err = list.Remove(0)
fmt.Println(err)
list.Print()
// Remove between
err = list.Remove(1)
fmt.Println(err)
list.Print()
// Remove last
err = list.Remove(1)
fmt.Println(err)
list.Print()
// Remove inexistent position
err = list.Remove(10)
fmt.Println(err)
list.Print()
// Remove last
err = list.Remove(0)
fmt.Println(err)
list.Print()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment