Skip to content

Commit af4ee26

Browse files
committed
added singly linked list in go (requested in issue #980)
1 parent 7d234ef commit af4ee26

File tree

1 file changed

+297
-0
lines changed

1 file changed

+297
-0
lines changed

Linked List/singly_linked_list.go

+297
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
/*
9+
insertAtTail (val)
10+
insertAtHead (val)
11+
deleteAtTail ()
12+
deleteAtHead ()
13+
getLength ()
14+
print ()
15+
getAtIdx (idx)
16+
replaceAtIdx (val, idx)
17+
deleteAtIdx (idx)
18+
search (val)
19+
toArray ()
20+
reverse ()
21+
*/
22+
23+
// struct for a node type, we use interface{} to allow for any type of value, you could replace this
24+
// with another value if you want to have more control over the type of value that can be inserted
25+
type node struct {
26+
val interface{}
27+
next *node
28+
}
29+
30+
// struct for the linked list type
31+
type linkedList struct {
32+
head *node
33+
tail *node
34+
length int
35+
}
36+
37+
// constructor for a node type
38+
func newNode(val interface{}) *node {
39+
return &node{val: val, next: nil}
40+
}
41+
42+
// constructor for a linked list type
43+
func newLinkedList() *linkedList {
44+
return &linkedList{head: nil, tail: nil, length: 0}
45+
}
46+
47+
// function for linked lists to check if the linked list is empty
48+
func (l *linkedList) IsEmpty() bool {
49+
return l.head == nil
50+
}
51+
52+
// function for linked lists to insert a value at the tail of the linked list
53+
func (l *linkedList) insertAtTail(val interface{}) {
54+
node := newNode(val)
55+
if l.IsEmpty() {
56+
l.head = node
57+
l.tail = l.head
58+
l.length += 1
59+
return
60+
} else {
61+
node := node
62+
l.tail.next = node
63+
l.tail = node
64+
l.length += 1
65+
}
66+
}
67+
68+
// function for linked lists to insert a value at the head of the linked list
69+
70+
func (l *linkedList) insertAtHead(val interface{}) {
71+
// create a new node
72+
node := newNode(val)
73+
// check if the list is empty
74+
if l.IsEmpty() {
75+
// if it is, set the head and tail to the new node and increase the length
76+
l.head = node
77+
l.tail = l.head
78+
l.length += 1
79+
return
80+
} else {
81+
// if it is not, set the new node's next to the current head and set the head to the new node
82+
node.next = l.head
83+
l.head = node
84+
l.length += 1
85+
}
86+
87+
}
88+
89+
func (l *linkedList) print() {
90+
c := l.head
91+
for c != nil {
92+
fmt.Printf("%v", c.val)
93+
if c.next == nil {
94+
fmt.Println()
95+
break
96+
}
97+
c = c.next
98+
99+
fmt.Print(" -> ")
100+
}
101+
fmt.Printf("Current Length: %v\n", l.length)
102+
103+
}
104+
105+
// function for linked lists to delete a node at the tail of the linked list
106+
func (l *linkedList) deleteAtTail() {
107+
if l.IsEmpty() {
108+
fmt.Println("Empty List")
109+
return
110+
}
111+
112+
if l.head.next == nil {
113+
l.head = nil
114+
l.tail = nil
115+
l.length -= 1
116+
return
117+
}
118+
119+
c := l.head
120+
for {
121+
if c.next.next == nil {
122+
c.next = nil
123+
l.tail = c
124+
l.length -= 1
125+
return
126+
}
127+
c = c.next
128+
}
129+
130+
}
131+
132+
// function for linked lists to delete a node at the head of the linked list
133+
func (l *linkedList) deleteAtHead() {
134+
if l.IsEmpty() {
135+
fmt.Println("Empty List")
136+
return
137+
}
138+
139+
if l.head.next == nil {
140+
l.head = nil
141+
l.tail = nil
142+
l.length -= 1
143+
return
144+
}
145+
146+
l.head = l.head.next
147+
l.length -= 1
148+
}
149+
150+
// function for linked lists to get the length of the linked list
151+
func (l *linkedList) getLength() int {
152+
return l.length
153+
}
154+
155+
// function of a linked list to get the value at a given index
156+
func (l *linkedList) getAtIdx(idx int) (interface{}, error) {
157+
if idx >= l.length {
158+
return nil, errors.New("index out of range")
159+
}
160+
161+
c := l.head
162+
for i := 0; i < idx; i++ {
163+
c = c.next
164+
}
165+
166+
return c.val, nil
167+
}
168+
169+
// function of a linked list to replace the value at a given index
170+
// index starts at 0
171+
func (l *linkedList) replaceAtIdx(val interface{}, idx int) error {
172+
if idx >= l.length {
173+
return errors.New("index out of range")
174+
}
175+
176+
c := l.head
177+
for i := 0; i < idx; i++ {
178+
c = c.next
179+
}
180+
181+
c.val = val
182+
return nil
183+
}
184+
185+
// function of a linked list to delete the value at a given index
186+
func (l *linkedList) deleteAtIdx(idx int) error {
187+
if idx >= l.length {
188+
return errors.New("index out of range")
189+
}
190+
191+
c := l.head
192+
for i := 0; i < idx-1; i++ {
193+
c = c.next
194+
}
195+
196+
c.next = c.next.next
197+
l.length -= 1
198+
return nil
199+
}
200+
201+
// function to find the index of a given value
202+
// returns -1 and an error if the value is not found
203+
func (l *linkedList) search(val interface{}) (int, error) {
204+
c := l.head
205+
for i := 0; i < l.length; i++ {
206+
if c.val == val {
207+
return i, nil
208+
}
209+
c = c.next
210+
}
211+
212+
return -1, errors.New("value not found")
213+
}
214+
215+
// function to convert a linked list to an array
216+
func (l *linkedList) toArray() []interface{} {
217+
arr := make([]interface{}, l.length)
218+
c := l.head
219+
for i := 0; i < l.length; i++ {
220+
arr[i] = c.val
221+
c = c.next
222+
}
223+
224+
return arr
225+
}
226+
227+
// function to reverse the linked list
228+
// This is a recursive implementation to show something different
229+
func (l *linkedList) reverse() error {
230+
if l.IsEmpty() {
231+
return errors.New("Empty List")
232+
}
233+
l.head = reverseListRecursive(l.head)
234+
return nil
235+
}
236+
237+
// recursive function to reverse a linked list recursively
238+
func reverseListRecursive(head *node) *node {
239+
if head == nil || head.next == nil {
240+
return head
241+
}
242+
243+
rest := reverseListRecursive(head.next)
244+
head.next.next = head
245+
head.next = nil
246+
247+
return rest
248+
}
249+
250+
// example of a linked list
251+
func main() {
252+
list := newLinkedList()
253+
254+
list.insertAtHead(1)
255+
list.insertAtTail(2)
256+
list.insertAtTail(3)
257+
list.insertAtTail(4)
258+
list.insertAtTail(5)
259+
list.insertAtTail(6)
260+
list.insertAtTail(7)
261+
list.insertAtTail(8)
262+
list.insertAtTail(9)
263+
list.insertAtTail(10)
264+
list.insertAtTail(11)
265+
list.print()
266+
267+
list.deleteAtTail()
268+
list.print()
269+
270+
err := list.replaceAtIdx(9000, 4)
271+
if err != nil {
272+
fmt.Println(err)
273+
}
274+
list.print()
275+
276+
i, err := list.search(9000)
277+
if err != nil {
278+
fmt.Println(err)
279+
} else {
280+
fmt.Println(i)
281+
}
282+
283+
err = list.reverse()
284+
if err != nil {
285+
fmt.Println(err)
286+
}
287+
288+
list.print()
289+
idx, err := list.search(3)
290+
if err != nil {
291+
fmt.Println(err)
292+
} else {
293+
fmt.Println(idx)
294+
}
295+
fmt.Println(list.toArray())
296+
297+
}

0 commit comments

Comments
 (0)