forked from AllAlgorithms/javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsinglyLinkedList.js
More file actions
239 lines (224 loc) · 7.81 KB
/
singlyLinkedList.js
File metadata and controls
239 lines (224 loc) · 7.81 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// Implementation of single link list
// Author: Sheary Tan
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
class SinglyList {
constructor() {
// Initializing...
// There is nothing at the beginning so
// the head & the tail should be empty,
// and the length should be zero too
this.head = null;
this.tail = null;
this.length = 0;
}
// 1st method: push (push the val into the end of the list)
push(val) {
// Firstly, we have to accept a new value
var newNode = new Node(val);
// If there is no head, means there is nothing on the list,
// set the head & tail pointers to this value.
if(!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
// If there is value existed, assign the newNode to the next value
// of the current existing value
this.tail.next = newNode;
// Update the tail to it!
this.tail = newNode;
}
// Increment the length and return the newly created link-list
this.length++;
return this;
}
// 2nd method: pop (remove the last item)
pop() {
// If there is nothing on the list, return undefined
if (!this.head) return undefined;
// Loop through to find the last item
var current = this.head;
var newTail = current;
while(current.next) {
newTail = current;
current = current.next
}
// Set the found tail to tail
this.tail = newTail;
// The next one will be null since we
// would like to remove it
this.tail.next = null;
// Decrease the length
this.length--;
// If there is nothing left after removing
// set the head and tail to be null
if(this.length === 0) {
this.head = null;
this.tail = null;
}
return current;
}
// 3rd method: shift (remove the first item)
shift() {
// If there is no nothing on the list, return undefined
if(!this.head) return undefined;
// Store the current head in a new variable
var currentHead = this.head;
// Shift the head to the next value of the currentHead
this.head = currentHead.next;
// Decrement the length since we have removed the head
this.length--;
if(this.length === 0) {
this.head = null;
this.tail = null;
}
return currentHead;
}
// 4th method: unshift (add item to the beginning )
unshift(val) {
// Initialize the value to a new node;
var newNode = new Node(val);
// If there is nothing on the list, set the head and tail
// point to that new node
if(!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
// In order to set the head value points to the head,
// we have to set the current head to the next item of newNode
newNode.next = this.head;
// and now we can assign the head to newNode!
this.head = newNode
}
// Increment the length after adding the new head
this.length++;
return this;
}
// 5th method: get
get(i) {
// get accepts an index in and find the specific value
// If i is less than zero, or greater and equal to the length
// of the current link list, return null;
if(i < 0 || i >= this.length) return null;
// Use the counter to find the value
var counter = 0;
var current = this.head;
while(counter !== i) {
current = current.next;
counter++
}
// Found it and return
return current
}
// 6th method: set
// Use the given index to find the target value and change it with the new
// given value
set(i, val) {
var targetNode = this.get(i);
if(targetNode) {
targetNode.val = val;
return true;
}
return false;
}
// 8th method: remove (from any index)
remove(i) {
// Check if there's anything on the list
if(i < 0 || i >= this.length) return undefined;
if(i === 0) return this.shift();
if(i === this.length - 1) return this.pop();
// Get the previous item of the target
var previousTarget = this.get(i - 1);
// Since we've got the previous item of the target,
// we now can remove the target by setting the next item of previousTarget
// to the next item of "removed"
var removed = previousTarget.next;
previousTarget.next = removed.next
// Decrease the length
this.length--;
return removed;
}
// 9th method: reverse
reverse() {
// Firstly we have to set the head to the tail,
// and the tail to the head
var target = this.head;
this.head = this.tail;
this.tail = target;
// Now we have to re-arrange those next & previous
// items of the list
var next;
var prev = null;
// Loop through every single item on the list
for(let i = 0; i < this.length; i++) {
// This part is a bit confusing, let's take an example
// Example = [1, 2, 3, 4, 5], T = target, P = previous, N = next
next = target.next;
// Firstly, the target is 1
// [1, 2, 3, 4, 5]
// T
// And target.next is 2
// [1, 2, 3, 4, 5]
// T N
target.next = prev;
// Remember our target is 1 & prev is null? Now it said the next item of
// 1 is null,
// 1 -> null
prev = target;
// Now we're setting the "prev = null" to the target value
// which now equals to "prev = 1"
// [1, 2, 3, 4, 5]
// P N
target = next;
// And lastly we set the "next" value to be T
// [1, 2, 3, 4, 5]
// P T
// So the cycle repeats again, now let's go through 1 more cycle
// [1, 2, 3, 4, 5]
// P T
// next = target.next
// [1, 2, 3, 4, 5]
// P T N
// target.next = prev
// Remember we have the list (1 -> null)?
// now target.next = prev means the next item of 2 is 1
// 2 -> 1 -> null
// prev = target
// Now 2 is prev
// [1, 2, 3, 4, 5]
// P N
// target = next
// And 3 is now the target
// [1, 2, 3, 4, 5]
// P T
// And the cycle repeats again until the target reach the end of the list...
}
return this;
}
// 10th method: insert
insert(i, val) {
// Check the requirements
if(i < 0 || i >= this.length) return false;
if(i === this.length) return !!this.push(val);
if(i === 0) return !!this.unshift(val);
// Initialize a new node
var newNode = new Node(val);
// Get the previous node of newNode
var prevNode = this.get(i - 1);
// Remember we haven't insert the newNode into the list!
// And also store the next item of prevNode in a temporary variable
// because we are going to set it to the next item of newNode later
var temp = prevNode.next;
// Now we can set the next item of prevNode to newNode
prevNode.next = newNode;
// Then the next item of newNode will be the temporary item we store
newNode.next = temp;
// Increment the length
this.length++;
return true;
}
}