-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlist.go
120 lines (106 loc) · 1.98 KB
/
list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package list
import (
"fmt"
)
// Node of list
type Node[V any] struct {
Value V
Prev, Next *Node[V]
}
// List is double linked list
type List[V any] struct {
length int
Head, Tail *Node[V]
}
// Len returns length of List
func (l *List[V]) Len() int {
return l.length
}
// New retruns a new an empty list
func New[V any]() *List[V] {
return &List[V]{}
}
// PushHead push value of element into the head of list
func (l *List[V]) PushHead(v V) {
l.PushHeadNode(&Node[V]{
Value: v,
})
}
// PushHeadNode push element into the head of list
func (l *List[V]) PushHeadNode(n *Node[V]) {
defer func() {
l.length++
}()
n.Prev = nil
n.Next = l.Head
if l.Head != nil {
l.Head.Prev = n
} else {
l.Tail = n
}
l.Head = n
}
// PushTail push value of element into the tail of list
func (l *List[V]) PushTail(v V) {
l.PushTailNode(&Node[V]{
Value: v,
})
}
// PushTailNode push element into the tail of list
func (l *List[V]) PushTailNode(n *Node[V]) {
defer func() {
l.length++
}()
n.Next = nil
n.Prev = l.Tail
if l.Tail != nil {
l.Tail.Next = n
} else {
l.Head = n
}
l.Tail = n
}
// Each calls `fn` on each Node from n onward in the list
func (n *Node[V]) Each(fn func(val V)) {
node := n
for node != nil {
fn(node.Value)
node = node.Next
}
}
// ReverseEach calls `fn` on each Node from n backward in the list
func (n *Node[V]) ReverseEach(fn func(val V)) {
node := n
for node != nil {
fn(node.Value)
node = node.Prev
}
}
// Remove n form list
func (l *List[V]) Remove(n *Node[V]) {
defer func() {
l.length--
}()
if n.Next != nil {
n.Next.Prev = n.Prev
} else {
l.Tail = n.Prev
}
if n.Prev != nil {
n.Prev.Next = n.Next
} else {
l.Head = n.Next
}
}
// String returns a string with all the message of list,
// you can print it out to know all about the list.
func (l *List[V]) String() (str string) {
if l == nil {
return
}
l.Head.Each(func(val V) {
str += fmt.Sprintf(" %v <=>", val)
})
str += fmt.Sprintf(" length: %d", l.length)
return str
}