-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlinked_list.go
159 lines (145 loc) · 3.56 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package collection
// DLList is a doubly linked list. It is based on the linked list implementation.
// It can be used as a stack and/or a queue.
// All the operations are O(1), even when the size of the list is large.
//
// The zero value for DLList is an empty list ready to use.
// var queue collection.DLList[int]
// queue.PushBack(1)
// queue.PushBack(2)
// queue.PushBack(3)
// fmt.Println(queue.PopFront()) // 1, true
// fmt.Println(queue.PopFront()) // 2, true
// fmt.Println(queue.PopFront()) // 3, true
// fmt.Println(queue.PopFront()) // 0, false
type DLList[T any] struct {
head *node[T]
tail *node[T]
size int
}
// Back returns the last element of the list.
// If the list is empty, the zero value is returned and false.
func (ll *DLList[T]) Back() (T, bool) {
if ll.size == 0 {
return *new(T), false
}
return ll.tail.value, true
}
// Clear removes all elements from the list.
func (ll *DLList[T]) Clear() {
ll.head = nil
ll.tail = nil
ll.size = 0
}
// Front returns the first element of the list.
// If the list is empty, the zero value is returned and false.
func (ll *DLList[T]) Front() (T, bool) {
if ll.size == 0 {
return *new(T), false
}
return ll.head.value, true
}
// IsEmpty returns true if the list is empty.
func (ll *DLList[T]) IsEmpty() bool {
return ll.size == 0
}
// Iter returns a new iterator for the list, iterating the values from front to back.
func (ll *DLList[T]) Iter() Iterator[T] {
cur_node := ll.head
return func() (T, bool) {
if cur_node == nil {
return *new(T), false
}
v := cur_node.value
cur_node = cur_node.next
return v, true
}
}
// Len returns the number of elements in the list.
func (ll *DLList[T]) Len() int {
return ll.size
}
// PopBack removes the last element from the list.
// If the second return value is false, the list is empty and the zero value is returned.
func (ll *DLList[T]) PopBack() (T, bool) {
if ll.size == 0 {
return *new(T), false
}
n := ll.tail
if ll.size == 1 {
ll.head = nil
ll.tail = nil
} else {
ll.tail = n.prev
ll.tail.next = nil
}
ll.size--
return n.value, true
}
// PopFront removes the first element from the list.
// If the second return value is false, the list is empty and the zero value is returned.
func (ll *DLList[T]) PopFront() (T, bool) {
if ll.size == 0 {
return *new(T), false
}
n := ll.head
if ll.size == 1 {
ll.head = nil
ll.tail = nil
} else {
ll.head = n.next
ll.head.prev = nil
}
ll.size--
return n.value, true
}
// PushBack adds a new element at the back of the list.
func (ll *DLList[T]) PushBack(v T) {
n := &node[T]{value: v}
if ll.size == 0 {
ll.head = n
ll.tail = n
} else {
ll.tail.next = n
n.prev = ll.tail
ll.tail = n
}
ll.size++
}
// PushFront adds a new element at the front of the list.
func (ll *DLList[T]) PushFront(v T) {
n := &node[T]{value: v}
if ll.size == 0 {
ll.head = n
ll.tail = n
} else {
ll.head.prev = n
n.next = ll.head
ll.head = n
}
ll.size++
}
// ReverseIter returns a new iterator for the list, iterating the values from back to front.
func (ll *DLList[T]) ReverseIter() Iterator[T] {
cur_node := ll.tail
return func() (T, bool) {
if cur_node == nil {
return *new(T), false
}
v := cur_node.value
cur_node = cur_node.prev
return v, true
}
}
// Size returns the number of elements in the list.
//
// Deprecated: Size is deprecated, use Len instead.
func (ll *DLList[T]) Size() int {
return ll.size
}
// node is a helper struct that holds the value and the links to the next and previous nodes.
type node[T any] struct {
value T
prev *node[T]
next *node[T]
}