-
Notifications
You must be signed in to change notification settings - Fork 0
/
linked_list.go
132 lines (108 loc) · 2.41 KB
/
linked_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
121
122
123
124
125
126
127
128
129
130
131
132
package streedb
import (
"cmp"
)
// LinkedList is a LL with specific methods to order in ascending or descending order
// it allows also duplicate values
type LinkedList[O cmp.Ordered, T Comparable[O]] struct {
head *LLNode[O, T]
}
// LLNode represents a LLNode in the doubly linked list
type LLNode[O cmp.Ordered, T Comparable[O]] struct {
Val T
Next *LLNode[O, T]
}
func (dll *LinkedList[O, T]) Head() (*LLNode[O, T], bool) {
if dll.head == nil {
return nil, false
}
return dll.head, true
}
func (dll *LinkedList[O, T]) Last() (T, bool) {
if dll.head == nil {
return *(new(T)), false
}
current := dll.head
for current.Next != nil {
current = current.Next
}
return current.Val, true
}
func (dll *LinkedList[O, T]) SetMax(value T) {
newNode := &LLNode[O, T]{Val: value}
if dll.head == nil {
dll.head = newNode
return
}
var last *LLNode[O, T]
for current := dll.head; current != nil; current, last = current.Next, current {
if current.Val.LessThan(value) {
// less than head value
if last == nil {
newNode.Next = current
dll.head = newNode
return
}
newNode.Next = current
last.Next = newNode
return
}
}
last.Next = newNode
}
func (dll *LinkedList[O, T]) SetMin(value T) {
newNode := &LLNode[O, T]{Val: value}
if dll.head == nil {
dll.head = newNode
return
}
var last *LLNode[O, T]
for current := dll.head; current != nil; current, last = current.Next, current {
if value.LessThan(current.Val) {
// less than head value
if last == nil {
newNode.Next = current
dll.head = newNode
return
}
newNode.Next = current
last.Next = newNode
return
}
}
if last != nil {
last.Next = newNode
} else {
dll.head = newNode
}
}
// Remove removes a node from the list
func (dll *LinkedList[O, T]) Remove(value T) {
var last *LLNode[O, T]
for current := dll.head; current != nil; current, last = current.Next, current {
if value.Equals(current.Val) {
// remove the head
if last == nil {
dll.head = current.Next
return
}
// remove the last node
if current.Next == nil {
last.Next = nil
return
}
// remove a node in the middle
last.Next = current.Next
return
}
}
}
// TraverseForward traverses the list from head to tail
func (dll *LinkedList[O, T]) Each(f func(T) bool) {
for current := dll.head; current != nil; current = current.Next {
cont := f(current.Val)
if !cont {
return
}
}
}