First night of doing the data structures.

master
Zed A. Shaw 4 weeks ago
commit d29998a797
  1. 32
      .gitignore
  2. 6
      Makefile
  3. 100
      dlist/impl.go
  4. 11
      go.mod
  5. 10
      go.sum
  6. 106
      llist/impl.go
  7. 8
      main.go
  8. 41
      tests/double_list_test.go
  9. 37
      tests/linked_list_test.go
  10. 30
      tests/ternary_tree_test.go
  11. 120
      tst/impl.go

32
.gitignore vendored

@ -0,0 +1,32 @@
# ---> Vim
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
backup
*.exe
*.dll
coverage
coverage/*
.venv
*.gz
config.toml
public
*.idx
*.sqlite3

@ -0,0 +1,6 @@
test:
go test MY/dsa/tests -v
build:
go build .

@ -0,0 +1,100 @@
package dlist
import (
"fmt"
)
type Node struct {
Data any
Next *Node
Prev *Node
}
type DLinkedList struct {
Front *Node
End *Node
Count int
}
func (l *DLinkedList) Add(data any) {
el := Node{data, nil, nil}
if l.Front == nil {
l.Front = &el
l.End = &el
} else {
l.End.Next = &el
el.Prev = l.End
l.End = &el
}
l.Count++
}
func (l *DLinkedList) Find(data any) (*Node) {
for el := l.Front; el != nil; el = el.Next {
if el.Data == data {
return el
}
}
return nil
}
func (l *DLinkedList) Delete(target *Node) {
if target == l.Front {
l.PopFront()
} else if target == l.End {
l.PopBack()
} else {
prev := target.Prev
prev.Next = target.Next
}
l.Count--
}
func (l *DLinkedList) PopBack() (*Node) {
if l.Front == nil {
return nil
} else if l.Front == l.End {
el := l.End
l.Front = nil
l.End = nil
l.Count = 0
return el
} else {
el := l.End
l.End = el.Prev
l.End.Next = nil
l.Count--
return el
}
}
func (l *DLinkedList) PopFront() (*Node) {
if l.Front == nil {
return nil
} else if l.Front == l.End {
el := l.Front
l.Front = nil
l.End = nil
l.Count = 0
return el
} else {
el := l.Front
next := l.Front.Next
l.Front = next
next.Prev = nil
l.Count--
return el
}
}
func (l *DLinkedList) Dump() {
fmt.Println("----------------", l.Count, "nodes")
for cur := l.Front; cur != nil; cur = cur.Next {
fmt.Println(cur.Data)
}
}

@ -0,0 +1,11 @@
module MY/dsa
go 1.24.2
require github.com/stretchr/testify v1.11.1
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,106 @@
package llist
import (
"fmt"
)
type Node struct {
Data any
Next *Node
}
type LinkedList struct {
Front *Node
End *Node
Count int
}
func (l *LinkedList) Add(data any) {
el := Node{data, nil}
if l.Front == nil {
l.Front = &el
l.End = &el
} else {
l.End.Next = &el
l.End = &el
}
l.Count++
}
func (l *LinkedList) Find(data any) (*Node) {
for el := l.Front; el != nil; el = el.Next {
if el.Data == data {
return el
}
}
return nil
}
func (l *LinkedList) Delete(target *Node) {
if l.Front == target {
l.PopFront()
} else if l.End == target {
l.PopBack()
} else {
el := l.Front
for el.Next != target {
el = el.Next
}
el.Next = el.Next.Next
target.Next = nil
l.Count--
}
}
func (l *LinkedList) PopBack() (*Node) {
el := l.End
if l.Front == nil {
return nil
} else if l.Front == l.End {
l.Front = nil
l.End = nil
l.Count--
} else {
new_end := l.Front
for new_end.Next.Next != nil {
new_end = new_end.Next
}
l.End = new_end
l.End.Next = nil
l.Count--
}
return el
}
func (l *LinkedList) PopFront() (*Node) {
el := l.Front
if l.Front == nil {
return nil
} else if l.Front == l.End {
l.Front = nil
l.End = nil
l.Count--
} else {
l.Front = l.Front.Next
l.Count--
}
return el
}
func (l *LinkedList) Dump() {
fmt.Println("----------------", l.Count, "nodes")
for cur := l.Front; cur != nil; cur = cur.Next {
fmt.Println(cur.Data)
}
}

@ -0,0 +1,8 @@
package main
import (
"fmt"
)
func main() {
fmt.Println("nothing here")
}

@ -0,0 +1,41 @@
package tests
import (
"testing"
"github.com/stretchr/testify/assert"
"MY/dsa/dlist"
)
func TestDoubleLinkedList(t *testing.T) {
list := dlist.DLinkedList{}
assert.Nil(t, list.PopBack())
assert.Nil(t, list.PopFront())
list.Add("front")
assert.Equal(t, list.End.Data, "front")
list.Add("back")
list.Dump()
assert.Equal(t, list.End.Data, "back")
back := list.PopBack()
assert.Equal(t, back.Data, "back")
list.Add("middle1")
list.Add("middle2")
list.Add("back2")
list.Dump()
back = list.PopBack()
assert.Equal(t, back.Data, "back2")
front := list.PopFront()
assert.Equal(t, front.Data, "front")
list.Dump()
middle := list.Find("middle2")
assert.Equal(t, middle.Data, "middle2")
list.Delete(middle)
list.Dump()
}

@ -0,0 +1,37 @@
package tests
import (
"testing"
"github.com/stretchr/testify/assert"
"MY/dsa/llist"
)
func TestLinkedList(t *testing.T) {
list := llist.LinkedList{}
assert.Nil(t, list.PopBack())
assert.Nil(t, list.PopFront())
list.Add("front")
list.Add("back")
list.Dump()
back := list.PopBack()
assert.Equal(t, back.Data, "back")
list.Add("middle1")
list.Add("middle2")
list.Add("back2")
list.Dump()
back = list.PopBack()
assert.Equal(t, back.Data, "back2")
front := list.PopFront()
assert.Equal(t, front.Data, "front")
list.Dump()
middle := list.Find("middle2")
assert.Equal(t, middle.Data, "middle2")
list.Delete(middle)
list.Dump()
}

@ -0,0 +1,30 @@
package tests
import (
"testing"
"github.com/stretchr/testify/assert"
"MY/dsa/tst"
)
func TestTernarySearchTree(t *testing.T) {
tree := tst.TST{}
tree.Add("hello", 100)
hello := tree.Get("hello")
assert.Equal(t, 100, hello)
tree.Add("howdy", 200)
howdy := tree.Get("howdy")
assert.Equal(t, 200, howdy)
nope := tree.Get("nope")
assert.Equal(t, nil, nope)
tree.Delete("howdy")
howdy = tree.Get("howdy")
assert.Equal(t, nil, howdy)
maybe := tree.StartsWith("ho")
assert.Equal(t, 200, maybe.Value)
}

@ -0,0 +1,120 @@
package tst
import (
)
type TST struct {
Root *Node
}
type Node struct {
Char rune
Value any
Less *Node
Equal *Node
Greater *Node
}
func (t *TST) Add(key string, value any) {
if t.Root == nil {
// first run, setup with the start letter
t.Root = &Node{rune(key[0]), nil, nil, nil, nil}
}
pos := t.Root
for _, ch := range key {
if ch < pos.Char {
if pos.Less == nil {
pos.Less = &Node{ch, nil, nil, nil, nil}
}
pos = pos.Less
} else if ch > pos.Char {
if pos.Greater == nil {
pos.Greater = &Node{ch, nil, nil, nil, nil}
}
pos = pos.Greater
} else if ch == pos.Char {
if pos.Equal == nil {
pos.Equal = &Node{ch, nil, nil, nil, nil}
}
pos = pos.Equal
}
pos.Value = value
}
}
func (t *TST) Find(key string) (*Node) {
if t.Root == nil {
return nil
}
pos := t.Root
next := t.Root
for _, ch := range key {
if ch < pos.Char {
next = pos.Less
} else if ch > pos.Char {
next = pos.Greater
} else if ch == pos.Char {
next = pos.Equal
}
if next == nil {
return nil
} else {
pos = next
}
}
return pos
}
func (t *TST) Get(key string) any {
node := t.Find(key)
if node == nil {
return nil
} else {
return node.Value
}
}
func (t *TST) Delete(key string) {
node := t.Find(key)
if node != nil {
node.Value = nil
}
}
func (t *TST) StartsWith(key string) *Node {
if t.Root == nil {
return nil
}
pos := t.Root
next := t.Root
for _, ch := range key {
if ch < pos.Char {
next = pos.Less
} else if ch > pos.Char {
next = pos.Greater
} else if ch == pos.Char {
next = pos.Equal
pos = pos.Equal
}
if next == nil {
return pos
}
}
return pos
}
Loading…
Cancel
Save