This commit is contained in:
2019-05-10 18:01:15 +08:00
parent 80f32247f6
commit b60d5b4f3d
8 changed files with 791 additions and 5 deletions

View File

@@ -0,0 +1,108 @@
package linkedlist
type Node struct {
next *Node
value interface{}
}
func (node *Node) Value() interface{} {
return node.value
}
type LinkedList struct {
head *Node
size uint
}
func New() *LinkedList {
return &LinkedList{}
}
func (l *LinkedList) Size() uint {
return l.size
}
func (l *LinkedList) Push(v interface{}) {
l.size++
if l.head == nil {
l.head = &Node{value: v}
return
}
l.head = &Node{value: v, next: l.head}
}
func (l *LinkedList) PushNode(n *Node) {
l.size++
if l.head == nil {
l.head = n
return
}
n.next = l.head
l.head = n
}
func (l *LinkedList) Pop() (result interface{}, found bool) {
if n, ok := l.PopNode(); ok {
return n.value, ok
}
return nil, false
}
func (l *LinkedList) PopNode() (result *Node, found bool) {
if l.head == nil {
return nil, false
}
result = l.head
found = true
l.head = result.next
result.next = nil
l.size--
return
}
func (l *LinkedList) Remove(idx uint) (result *Node, found bool) {
if l.size == 0 {
return nil, false
}
if idx == 0 {
result = l.head
found = true
l.head = result.next
result.next = nil
l.size--
return
}
for cur := l.head; cur.next != nil; cur = cur.next {
if idx == 1 {
l.size--
result = cur.next
found = true
cur.next = result.next
result.next = nil
return
}
idx--
}
return nil, false
}
func (l *LinkedList) Values() (result []interface{}) {
l.Traversal(func(cur *Node) bool {
result = append(result, cur.value)
return true
})
return
}
func (l *LinkedList) Traversal(every func(*Node) bool) {
for cur := l.head; cur != nil; cur = cur.next {
if !every(cur) {
break
}
}
}

View File

@@ -0,0 +1,87 @@
package linkedlist
import (
"testing"
"github.com/davecgh/go-spew/spew"
)
func TestPush(t *testing.T) {
l := New()
for i := 0; i < 5; i++ {
l.Push(i)
}
var result string
result = spew.Sprint(l.Values())
if result != "[4 3 2 1 0]" {
t.Error(result)
}
l.Push(0)
result = spew.Sprint(l.Values())
if result != "[0 4 3 2 1 0]" {
t.Error(result)
}
}
func TestPop(t *testing.T) {
l := New()
for i := 0; i < 5; i++ {
l.Push(i)
}
if v, ok := l.Pop(); ok {
if v != 4 {
t.Error(v)
}
} else {
t.Error("Pop should ok, but is not ok")
}
var result string
result = spew.Sprint(l.Values())
if result != "[3 2 1 0]" {
t.Error(result)
}
for i := 3; l.Size() != 0; i-- {
if v, ok := l.Pop(); ok {
if v != i {
t.Error(i, v, "is not equals")
}
} else {
t.Error("Pop should ok, but is not ok", i)
}
}
l.Push(0)
result = spew.Sprint(l.Values())
if result != "[0]" {
t.Error(result)
}
if l.Size() != 1 {
t.Error("l.Size() == 1, but is error, size = ", l.Size())
}
}
func TestRemove(t *testing.T) {
l := New()
for i := 0; i < 5; i++ {
l.Push(i)
}
for i := 0; i < 5; i++ {
if n, ok := l.Remove(0); ok {
if n.Value() != 4-i {
t.Error(n)
}
} else {
t.Error("Pop should ok, but is not ok", i)
}
}
if l.Size() != 0 {
t.Error("l.Size() == 0, but is error, size = ", l.Size())
}
}