Skip to content

Repository files navigation

build statusgo reportgodoclicense

Introduction

Implement data structures with Go.

Table Of Content

Iterator

ValueIterator

The package provides six iterators as following.

ValueIterator traverses the value backward.

typeValueIteratorinterface {
Next() boolBegin()
Value() interface{}
}

ReverseValueIterator

ReverseValueIterator can traverse values forward or backward.

typeReverseValueIteratorinterface {
ValueIteratorPrev() boolEnd()
}

IndexIterator

IndexIterator traverses the index-value pair backward.

typeIndexIteratorinterface {
ValueIteratorIndex() int
}

ReverseIndexIterator

ReverseIndexIterator can traverse the index-value pair forward or backward.

typeReverseIndexIteratorinterface {
IndexIteratorPrev() boolEnd()
}

KeyIterator

KeyIterator traverses the key-value pair backward.

typeKeyIteratorinterface {
ValueIteratorKey() interface{}
}

ReverseKeyIterator

ReverseKeyIterator can traverse the key-value pair forward or backward.

typeReverseKeyIteratorinterface {
KeyIteratorPrev() boolEnd()
}

Different data structures have different support for iterator as following.

ds1.png

Container

All data structures will implement the Container interface.

typeContainerinterface {
Empty() boolSize() intClear()
Values() []interface{}
}

List

List is ordered and value repeatable.

Implements Container interface.

typeListinterface {
Append(values...interface{})
Get(indexint) (interface{}, error)
Remove(indexint) errorContains(values...interface{}) boolSwap(i, jint) errorInsert(indexint, values...interface{}) errorSet(indexint, valueinterface{}) errorIndexOf(valueinterface{}) (int, error)
container.Container// Empty() bool// Size() int// Clear()// Values() []interface{}
}

SinglyLinkedList

The current element of SinglyLinkedList points to the next element.

Implements List, ValueIterator and IndexIterator interface.

drawing

package main
import (
"fmt""github.com/prprprus/ds/list/singlylinkedlist"
)
funcmain() {
list:=singlylinkedlist.New() // []list.Append(1) // [1]list.Append(2) // [1, 2]list.Append(3) // [1, 2, 3]list.PreAppend(4) // [4, 1, 2, 3]_, _=list.Get(0) // 4, nil_, _=list.Get(999) // nil, ErrIndex_=list.Remove(2) // [4, 1, 3]_=list.Contains() // true_=list.Contains(4, 1) // true_=list.Contains(4, 3) // true_=list.Contains(4, 1, 3, 5) // false_=list.Swap(0, 1) // [1, 4, 3]_=list.Insert(1, 5, 6, 7, 8) // [1, 4, 5, 6, 7, 8, 3]_=list.Set(3, -1) // [1, 4, 5, -1, 7, 8, 3]// iteratorit:=list.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 1// 1 4// 2 5// 3 -1// 4 7// 5 8// 6 3_, _=list.IndexOf(1) // 0, nil_, _=list.IndexOf(8) // 5, nil_, _=list.IndexOf(100) // -1, ErrIndexOflist.Reverse() // [3, 8, 7, -1, 5, 4, 1]_=list.Empty() // false_=list.Size() // 7_=list.Values() // [3 8 7 -1 5 4 1]list.Clear() // []
}

DoubleLinkedList

The current and next elements of the DoubleLinkedList point to each other.

Implements List, ValueIterator, ReverseValueIterator, IndexIterator and ReverseIndexIterator interface.

drawing

package main
import (
"fmt""github.com/prprprus/ds/list/doublelinkedlist"
)
funcmain() {
list:=doublelinkedlist.New() // []list.Append(1) // [1]list.Append(2) // [1 2]list.Append(3) // [1 2 3]list.PreAppend(4) // [4 1 2 3]_, _=list.Get(0) // 4, nil_, _=list.Get(999) // nil, ErrIndex_=list.Remove(2) // [4 1 3]_=list.Contains() // true_=list.Contains(4, 1) // true_=list.Contains(4, 3) // true_=list.Contains(4, 1, 3, 5) // false_=list.Swap(0, 1) // [1 4 3]_=list.Insert(1, 5, 6, 7, 8) // [1 4 5 6 7 8 3]_=list.Set(3, -1) // [1 4 5 -1 7 8 3]// iteratorit:=list.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 1// 1 4// 2 5// 3 -1// 4 7// 5 8// 6 3it.End()
forit.Prev() {
fmt.Println(it.Index(), it.Value())
}
// output:// 6 3// 5 8// 4 7// 3 -1// 2 5// 1 4// 0 1_, _=list.IndexOf(1) // 0, nil_, _=list.IndexOf(8) // 5, nil_, _=list.IndexOf(100) // -1, ErrIndexOflist.Reverse() // [3 8 7 -1 5 4 1]_=list.Empty() // false_=list.Size() // 7_=list.Values() // [3 8 7 -1 5 4 1]list.Clear() // []
}

ArrayList

ArrayList is a dynamic array that can be dynamically scaled based on capacity and number of elements.

Implements List, ValueIterator, ReverseValueIterator, IndexIterator and ReverseIndexIterator interface.

drawing

package main
import (
"fmt""github.com/prprprus/ds/list/arraylist"
)
funcmain() {
list:=arraylist.New() // []list.Append(1) // [1]list.Append(2) // [1 2]list.Append(3) // [1 2 3]_, _=list.Get(0) // 1, nil_, _=list.Get(999) // nil, ErrIndex_=list.Remove(2) // [1 2]_=list.Contains() // true_=list.Contains(1, 2) // true_=list.Contains(2) // true_=list.Contains(1, 2, 3) // false_=list.Swap(0, 1) // [2 1]_=list.Insert(1, 5, 6, 7, 8) // [2 1 5 6 7 8]_=list.Set(3, -1) // [2 1 5 -1 7 8]// iteratorit:=list.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 2// 1 1// 2 5// 3 -1// 4 7// 5 8it.End()
forit.Prev() {
fmt.Println(it.Index(), it.Value())
}
// output:// 5 8// 4 7// 3 -1// 2 5// 1 1// 0 2_, _=list.IndexOf(1) // 1, nil_, _=list.IndexOf(8) // 5, nil_, _=list.IndexOf(100) // -1, ErrIndexOf_=list.Empty() // false_=list.Size() // 6_=list.Values() // [2 1 5 -1 7 8]list.Clear() // []
}

Stack

Stack is a FILO data structure.

Implements Container interface.

drawing

typeStackinterface {
Push(valueinterface{})
Pop() (interface{}, error)
Peek() (interface{}, error)
container.Container// Empty() bool// Size() int// Clear()// Values() []interface{}
}

LinkedListStack

LinkedListStack is a stack based on SinglyLinkedList.

Implements Stack, ValueIterator and IndexIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/stack/linkedliststack"
)
funcmain() {
stack:=linkedliststack.New() // []stack.Push(1) // [1]stack.Push(2) // [2 1]stack.Push(3) // [3 2 1]// iteratorit:=stack.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 3// 1 2// 2 1_, _=stack.Peek() // 3, nil_, _=stack.Pop() // 3, nil_, _=stack.Peek() // 2, nil_=stack.Empty() // false_=stack.Size() // 2_=stack.Values() // [2 1]stack.Clear() // []
}

ArrayStack

ArrayStack is a stack based on ArrayList.

Implements Stack, ValueIterator, ReverseValueIterator, IndexIterator and ReverseIndexIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/stack/arraystack"
)
funcmain() {
stack:=arraystack.New() // []stack.Push(1) // [1]stack.Push(2) // [2 1]stack.Push(3) // [3 2 1]// iteratorit:=stack.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 3// 1 2// 2 1_, _=stack.Peek() // 3, nil_, _=stack.Pop() // 3, nil_, _=stack.Peek() // 2, nil_=stack.Empty() // false_=stack.Size() // 2_=stack.Values() // [2 1]stack.Clear() // []
}

Queue

Queue is a FIFO data structure.

Implements Container interface.

drawing

typeQueueinterface {
Put(valueinterface{})
Get() (interface{}, error)
container.Container// Empty() bool// Size() int// Clear()// Values() []interface{}
}

LinkedListQueue

LinkedListQueue is a stack based on SinglyLinkedList.

Implements Queue, ValueIterator and IndexIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/queue/linkedlistqueue"
)
funcmain() {
queue:=linkedlistqueue.New() // []queue.Put(1) // [1]queue.Put(2) // [1 2]queue.Put(3) // [1 2 3]queue.Put(4) // [1 2 3 4]// iteratorit:=queue.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 1// 1 2// 2 3// 3 4_, _=queue.Get() // 1, nil_, _=queue.Get() // 2, nil_=queue.Empty() // false_=queue.Size() // 2_=queue.Values() // [3 4]queue.Clear() // []
}

ArrayQueue

ArrayQueue is a stack based on ArrayList.

Implements Queue, ValueIterator and IndexIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/queue/arrayqueue"
)
funcmain() {
queue:=arrayqueue.New() // []queue.Put(1) // [1]queue.Put(2) // [1 2]queue.Put(3) // [1 2 3]queue.Put(4) // [1 2 3 4]// iteratorit:=queue.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Index(), it.Value())
}
// output:// 0 1// 1 2// 2 3// 3 4_, _=queue.Get() // 1, nil_, _=queue.Get() // 2, nil_=queue.Empty() // false_=queue.Size() // 2_=queue.Values() // [3 4]queue.Clear() // []
}

SkipList

SkipList is a random data structure with performance comparable to that of red-black trees. It should be noted that the keys must be comparable types and element will be sorted by keys.

Implements Container, ValueIterator and KeyIterator interface.

drawing

package main
import (
"fmt""github.com/prprprus/ds/skiplist""github.com/prprprus/ds/util"
)
funcmain() {
skiplist:=skiplist.New(util.IntComparator) // []skiplist.Set(1, "a") // [{1: "a"}]skiplist.Set(2, "b") // [{1: "a"} {2: "b"}]skiplist.Set(3, "c") // [{1: "a"} {2: "b"} {3: "c"}]skiplist.Set(4, "d") // [{1: "a"} {2: "b"} {3: "c"} {4: "d"}]// iteratorit:=skiplist.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Key(), it.Value())
}
// output:// 1 a// 2 b// 3 c// 4 d_=skiplist.Exists(1) // true_=skiplist.Exists(9) // false_, _=skiplist.Get(1) // "a", nil_, _=skiplist.Get(3) // "c", nil_=skiplist.Remove(2) // nil_=skiplist.Keys() // [1 3 4]_=skiplist.Empty() // false_=skiplist.Size() // 3_=skiplist.Values() // [a c d]skiplist.Clear() // []
}

Map

Map stores key-value pairs with excellent operational performance. It should be noted that the keys must be comparable types.

Implements Container interface.

typeMapinterface {
Put(key, valueinterface{})
Get(keyinterface{}) (interface{}, error)
Remove(keyinterface{})
container.Container// Empty() bool// Size() int// Clear()// Values() []interface{}
}

HashMap

HashMap is a map based on hash table.

Implements Map interface.

drawing

package main
import (
"github.com/prprprus/ds/maps/hashmap"
)
funcmain() {
m:=hashmap.New() // []m.Put(1, "a") // [{1: "a"}]m.Put(2, "b") // [{1: "a"} {2: "b"}]m.Put(3, "c") // [{1: "a"} {2: "b"} {3: "c"}]m.Put(4, "d") // [{1: "a"} {2: "b"} {3: "c"} {4: "d"}]_=m.Keys() // [1 2 3 4] (Note: order of random)_, _=m.Get(1) // "a", nil_, _=m.Get(3) // "c", nil_=m.Remove(2) // nil_=m.Keys() // [1 3 4]_=m.Empty() // false_=m.Size() // 3_=m.Values() // [a c d] (Note: order of random)m.Clear() // []
}

LinkedHashMap

LinkedHashMap is a map based on hash table and DoubleLinkedList, it provides ordered key-value pairs.

Implements Map, ValueIterator, ReverseValueIterator, KeyIterator and ReverseKeyIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/maps/linkedhashmap"
)
funcmain() {
m:=linkedhashmap.New() // []m.Put(1, "a") // [{1: "a"}]m.Put(2, "b") // [{1: "a"} {2: "b"}]m.Put(3, "c") // [{1: "a"} {2: "b"} {3: "c"}]m.Put(4, "d") // [{1: "a"} {2: "b"} {3: "c"} {4: "d"}]// iteratorit:=m.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Key(), it.Value())
}
// output:// 1 a// 2 b// 3 c// 4 dit.End()
forit.Prev() {
fmt.Println(it.Key(), it.Value())
}
// output:// 4 d// 3 c// 2 b// 1 a_=m.Keys() // [1 2 3 4]_, _=m.Get(1) // "a", nil_, _=m.Get(3) // "c", nil_=m.Remove(2) // nil_=m.Keys() // [1 3 4]_=m.Empty() // false_=m.Size() // 3_=m.Values() // [a c d]m.Clear() // []
}

SkipMap

SkipMap is a map based on SkipList.

Implements Map, ValueIterator and KeyIterator.

package main
import (
"fmt""github.com/prprprus/ds/maps/linkedhashmap"
)
funcmain() {
m:=linkedhashmap.New() // []m.Put(1, "a") // [{1: "a"}]m.Put(2, "b") // [{1: "a"} {2: "b"}]m.Put(3, "c") // [{1: "a"} {2: "b"} {3: "c"}]m.Put(4, "d") // [{1: "a"} {2: "b"} {3: "c"} {4: "d"}]// iteratorit:=m.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Key(), it.Value())
}
// output:// 1 a// 2 b// 3 c// 4 d_=m.Keys() // [1 2 3 4]_, _=m.Get(1) // "a", nil_, _=m.Get(3) // "c", nil_=m.Remove(2) // nil_=m.Keys() // [1 3 4]_=m.Empty() // false_=m.Size() // 3_=m.Values() // [a c d]m.Clear() // []
}

Set

Set is used to store non-repeating values, usually with good operational performance.

Implements Container interface.

typeSetinterface {
Add(values...interface{})
Remove(values...interface{}) errorContains(values...interface{}) bool
container.Container// Empty() bool// Size() int// Clear()// Values() []interface{}
}

HashSet

HashSet is a set based on hash table.

Implements Set interface.

package main
import (
"github.com/prprprus/ds/set/hashset"
)
funcmain() {
s:=hashset.New() // []s.Add(1) // [1]s.Add(2) // [1 2]s.Add(3) // [1 2 3]_=s.Contains() // true_=s.Contains(1, 2, 3) // true_=s.Contains(1, 3) // true_=s.Contains(2, 3, 4) // false_=s.Remove(2) // nil_=s.Empty() // false_=s.Size() // 2_=s.Values() // [1 3]s.Clear() // []
}

LinkedHashSet

LinkedHashSet is a set based on hash table and DoubleLinkedList, it provides ordered value.

Implements Set, ValueIterator and ReverseValueIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/set/linkedhashset"
)
funcmain() {
s:=linkedhashset.New() // []s.Add(1) // [1]s.Add(2) // [1 2]s.Add(3) // [1 2 3]// iteratorit:=s.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Value())
}
// output:// 1// 2// 3it.End()
forit.Prev() {
fmt.Println(it.Value())
}
// output:// 3// 2// 1_=s.Contains() // true_=s.Contains(1, 2, 3) // true_=s.Contains(1, 3) // true_=s.Contains(2, 3, 4) // false_=s.Remove(2) // nil_=s.Empty() // false_=s.Size() // 2_=s.Values() // [1 3]s.Clear() // []
}

SkipSet

SkipSet is a set based on SkipList.

Implements Set and ValueIterator interface.

package main
import (
"fmt""github.com/prprprus/ds/set/skipset""github.com/prprprus/ds/util"
)
funcmain() {
s:=skipset.New(util.IntComparator) // []s.Add(1) // [1]s.Add(2) // [1 2]s.Add(3) // [1 2 3]// iteratorit:=s.Iterator()
it.Begin()
forit.Next() {
fmt.Println(it.Value())
}
// output:// 1// 2// 3_=s.Contains() // true_=s.Contains(1, 2, 3) // true_=s.Contains(1, 3) // true_=s.Contains(2, 3, 4) // false_=s.Remove(2) // nil_=s.Empty() // false_=s.Size() // 2_=s.Values() // [1 3]s.Clear() // []
}

Util

Contains some helper functions.

Comparator

Comparator provides the following built-in type of comparator.

funcIntComparator(a, binterface{}) intfuncInt8Comparator(a, binterface{}) intfuncInt16Comparator(a, binterface{}) intfuncInt32Comparator(a, binterface{}) intfuncInt64Comparator(a, binterface{}) intfuncUIntComparator(a, binterface{}) intfuncUInt8Comparator(a, binterface{}) intfuncUInt16Comparator(a, binterface{}) intfuncUInt32Comparator(a, binterface{}) intfuncUInt64Comparator(a, binterface{}) intfuncFloat32Comparator(a, binterface{}) intfuncFloat64Comparator(a, binterface{}) intfuncByteComparator(a, binterface{}) intfuncRuneComparator(a, binterface{}) intfuncStringComparator(a, binterface{}) int

The meaning of the return value is as follows.

-1 => a < b
0 => a == b
1 => a > b

For custom types, you can also create a corresponding comparator.

package main
import (
"fmt""github.com/prprprus/ds/set/skipset"
)
typePeoplestruct {
namestringageint
}
funcAgeComparator(a, binterface{}) int {
c1:=a.(People)
c2:=b.(People)
switch {
casec1.age<c2.age:
return-1casec1.age>c2.age:
return1default:
return0
}
}
funcmain() {
s:=skipset.New(AgeComparator)
s.Add(People{"Wade", 35})
s.Add(People{"Simon", 32})
s.Add(People{"yiyi", 22})
fmt.Println(s.Values()) // [{"yiyi", 22}, {"Simon", 32}, {"Wade", 35}]
}

Benchmarking

go test -run=NO_TEST -bench=. -benchmem -benchtime 1s github.com/prprprus/ds/...

ds-bench-1.pngds-bench-2.pngds-bench-3.pngds-bench-4.pngds-bench-5.pngds-bench-6.png

About

Implement Data Structures With Go.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages