-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinkedList.go
150 lines (118 loc) · 3.2 KB
/
linkedList.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
package algo
import (
"fmt"
"io"
)
type node struct {
data any
next *node
}
func NewNode(value any) *node {
return &node{
data: value,
}
}
type linkedList struct {
head *node
}
func NewLinkedList(value any) *linkedList {
return &linkedList{
head: NewNode(value),
}
}
// read returns node.data of the linkedList's given index.
func (ll *linkedList) read(index int) any {
currentNode := ll.head
for i := 0; i < index; i++ {
if currentNode.next == nil {
return nil
}
currentNode = currentNode.next
}
return currentNode.data
}
// indexOf search's linkedList for the given value and returns the index position.
func (ll *linkedList) indexOf(value any) int {
currentNode := ll.head
for i := 0; ; i++ {
if currentNode.data == value {
return i
}
if currentNode.next == nil {
return -1
}
currentNode = currentNode.next
}
}
// insertion will insert a new node at the given index.
// It returns false if the given index exceeds the length of linkedList.
func (ll *linkedList) insertAtIndex(index int, value any) bool {
newNode := NewNode(value)
if index == 0 {
newNode.next = ll.head
ll.head = newNode
return true
}
currentNode := ll.head
for i := 0; i < index-1; i++ { // Access the node immediately before the index position of the new node.
if currentNode.next == nil {
return false
}
currentNode = currentNode.next
}
newNode.next = currentNode.next
currentNode.next = newNode
return true
}
// deleteAtIndex delete a linkedList's node at the given index.
// It returns false if the given index exceeds the length of linkedList
func (ll *linkedList) deleteAtIndex(index int) bool {
if index == 0 { // Simply set the head as the next node if deleting first node.
ll.head = ll.head.next
return true
}
currentNode := ll.head
for i := 0; i < index-1; i++ { // Access the node immediately before the index position of the node to be deleted.
if currentNode.next == nil || currentNode.next.next == nil {
return false
}
currentNode = currentNode.next
}
nodeAfterDeletedNode := currentNode.next.next
currentNode.next = nodeAfterDeletedNode
return true
}
// iterate will traverse and print all elements and their index in a linkedList to the given io.Writer.
func (ll *linkedList) iterate(writer io.Writer) {
currentNode := ll.head
for currentNode != nil {
fmt.Fprintf(writer, "%v\n", currentNode.data)
currentNode = currentNode.next
}
}
// tail will return the last element of a linked list.
func (ll *linkedList) tail() any {
currentNode := ll.head
for currentNode.next != nil {
currentNode = currentNode.next
}
return currentNode.data
}
// flip will reverse the elements of a linkedList.
func (ll *linkedList) reverse() {
var previousNode *node
currentNode := ll.head
for currentNode != nil {
nextNode := currentNode.next
currentNode.next = previousNode
previousNode = currentNode
currentNode = nextNode
}
ll.head = previousNode
}
// deleteMiddleNode removes the node at the given pointer, retaining the linkedList integrity.
// This is useful if we have only a node's memory address, and can't infer what nodes come before it.
func (ll *linkedList) deleteMiddleNode(node *node) {
node.data = node.next.data
node.next = node.next.next
}