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