commit
d29998a797
@ -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,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…
Reference in new issue