Skip to content

Commit 2b5176d

Browse files
committed
Add a golang implementation for doubly linked list
1 parent 62fde88 commit 2b5176d

File tree

2 files changed

+196
-1
lines changed

2 files changed

+196
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,7 @@ Com o objetivo de alcançar uma abrangência maior e encorajar mais pessoas a co
20612061
</a>
20622062
</td>
20632063
<td> <!-- Go -->
2064-
<a href="./CONTRIBUTING.md">
2064+
<a href="./src/go/doubly_linked_list.go">
20652065
<img align="center" height="25" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/github/github-original.svg" />
20662066
</a>
20672067
</td>

src/go/doubly_linked_list.go

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package main
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
type Node struct {
9+
Value int
10+
Next *Node
11+
Prev *Node
12+
}
13+
14+
type DoublyLinkedList struct {
15+
Head *Node
16+
Tail *Node
17+
}
18+
19+
func (list *DoublyLinkedList) AddLeft(value int) {
20+
node := Node{Value: value}
21+
22+
if list.Head == nil {
23+
list.Head = &node
24+
list.Tail = &node
25+
return
26+
}
27+
28+
node.Next = list.Head
29+
list.Head.Prev = &node
30+
list.Head = &node
31+
}
32+
33+
func (list *DoublyLinkedList) AddRight(value int) {
34+
node := Node{Value: value}
35+
36+
if list.Tail == nil {
37+
list.Tail = &node
38+
list.Head = &node
39+
return
40+
}
41+
42+
node.Prev = list.Tail
43+
list.Tail.Next = &node
44+
list.Tail = &node
45+
}
46+
47+
func (list *DoublyLinkedList) RemoveLeft() {
48+
if list.Head == nil {
49+
return
50+
}
51+
52+
list.Head = list.Head.Next
53+
54+
if list.Head != nil {
55+
list.Head.Prev = nil
56+
} else {
57+
list.Tail = nil
58+
}
59+
}
60+
61+
func (list *DoublyLinkedList) RemoveRight() {
62+
if list.Tail == nil {
63+
return
64+
}
65+
66+
list.Tail = list.Tail.Prev
67+
68+
if list.Tail != nil {
69+
list.Tail.Next = nil
70+
} else {
71+
list.Head = nil
72+
}
73+
}
74+
75+
func (list *DoublyLinkedList) FindAt(idx int) *Node {
76+
pointer := list.Head
77+
78+
for i := 0; i < idx; i++ {
79+
pointer = pointer.Next
80+
if pointer == nil {
81+
return nil
82+
}
83+
}
84+
85+
return pointer
86+
}
87+
88+
func (list *DoublyLinkedList) AddAt(idx, value int) {
89+
if idx == 0 {
90+
list.AddLeft(value)
91+
return
92+
}
93+
94+
foundNode := list.FindAt(idx)
95+
if foundNode == nil {
96+
return
97+
}
98+
99+
prevNode := foundNode.Prev
100+
if prevNode == nil {
101+
return
102+
}
103+
104+
newNode := Node{Value: value}
105+
106+
newNode.Prev = prevNode
107+
newNode.Next = foundNode
108+
109+
prevNode.Next = &newNode
110+
foundNode.Prev = &newNode
111+
}
112+
113+
func (list *DoublyLinkedList) RemoveAt(idx int) {
114+
if idx == 0 {
115+
list.RemoveLeft()
116+
return
117+
}
118+
119+
foundNode := list.FindAt(idx)
120+
if foundNode == nil {
121+
return
122+
}
123+
124+
prevNode := foundNode.Prev
125+
if prevNode == nil {
126+
return
127+
}
128+
129+
prevNode.Next = foundNode.Next
130+
131+
if foundNode.Next == nil {
132+
list.Tail = prevNode
133+
return
134+
}
135+
136+
foundNode.Next.Prev = prevNode
137+
}
138+
139+
func (list *DoublyLinkedList) ToSlice() []int {
140+
var slice []int
141+
142+
for pointer := list.Head; pointer != nil; pointer = pointer.Next {
143+
slice = append(slice, pointer.Value)
144+
}
145+
146+
return slice
147+
}
148+
149+
func TestDoublyLinkedList(t *testing.T) {
150+
list := DoublyLinkedList{}
151+
152+
// test AddLeft
153+
list.AddLeft(1)
154+
list.AddLeft(2)
155+
if !reflect.DeepEqual(list.ToSlice(), []int{2, 1}) {
156+
t.Errorf("AddLeft failed, expected %v, got %v", []int{2, 1}, list.ToSlice())
157+
}
158+
159+
// test AddRight
160+
list.AddRight(3)
161+
list.AddRight(4)
162+
if !reflect.DeepEqual(list.ToSlice(), []int{2, 1, 3, 4}) {
163+
t.Errorf("AddRight failed, expected %v, got %v", []int{2, 1, 3, 4}, list.ToSlice())
164+
}
165+
166+
//// test RemoveLeft
167+
list.RemoveLeft()
168+
if !reflect.DeepEqual(list.ToSlice(), []int{1, 3, 4}) {
169+
t.Errorf("RemoveLeft failed, expected %v, got %v", []int{1, 3, 4}, list.ToSlice())
170+
}
171+
172+
// test RemoveRight
173+
list.RemoveRight()
174+
if !reflect.DeepEqual(list.ToSlice(), []int{1, 3}) {
175+
t.Errorf("RemoveRight failed, expected %v, got %v", []int{1, 3}, list.ToSlice())
176+
}
177+
178+
// test AddAt
179+
list.AddAt(1, 5)
180+
if !reflect.DeepEqual(list.ToSlice(), []int{1, 5, 3}) {
181+
t.Errorf("AddAt failed, expected %v, got %v", []int{1, 5, 3}, list.ToSlice())
182+
}
183+
184+
// test RemoveAt
185+
list.RemoveAt(2)
186+
if !reflect.DeepEqual(list.ToSlice(), []int{1, 5}) {
187+
t.Errorf("RemoveAt failed, expected %v, got %v", []int{1, 5}, list.ToSlice())
188+
}
189+
190+
// test FindAt
191+
node := list.FindAt(0)
192+
if node == nil || node.Value != 1 {
193+
t.Errorf("FindAt failed, expected %v, got %v", 1, node.Value)
194+
}
195+
}

0 commit comments

Comments
 (0)