11/* SinglyLinkedList!!
2- * A linked list is similar to an array, it holds a list of values.
3- * However, links in a linked list do not have indexes. With
4- * a linked list you do not need to predetermine its size as
5- * it grows and shrinks as it is edited. This is an example of
6- * a singly linked list.
7- */
2+ * A linked list is similar to an array, it holds a list of values.
3+ * However, links in a linked list do not have indexes. With
4+ * a linked list you do not need to predetermine its size as
5+ * it grows and shrinks as it is edited. This is an example of
6+ * a singly linked list.
7+ */
88
99// Methods - size, head, addLast, addFirst, addAt, removeFirst, removeLast, remove, removeAt, indexOf, isEmpty, elementAt, findMiddle, get, clean, rotateListRight
1010
@@ -18,6 +18,7 @@ class Node {
1818class LinkedList {
1919 constructor ( listOfValues ) {
2020 this . headNode = null
21+ this . tailNode = null
2122 this . length = 0
2223
2324 if ( listOfValues instanceof Array ) {
@@ -42,6 +43,11 @@ class LinkedList {
4243 return this . headNode ?. data || null
4344 }
4445
46+ // Returns the tail
47+ tail ( ) {
48+ return this . tailNode ?. data || null
49+ }
50+
4551 // Return if the list is empty
4652 isEmpty ( ) {
4753 return this . length === 0
@@ -53,23 +59,22 @@ class LinkedList {
5359 if ( this . headNode === null ) {
5460 return this . addFirst ( element )
5561 }
56- let { currentNode } = this . initiateNodeAndIndex ( )
57-
58- // Loop till there is a node present in the list
59- while ( currentNode . next ) {
60- currentNode = currentNode . next
61- }
62-
6362 const node = new Node ( element )
6463 // Adding node at the end of the list and increase the length
65- currentNode . next = node
64+ this . tailNode . next = node
65+ this . tailNode = node
6666 this . length ++
6767 return this . size ( )
6868 }
6969
7070 // add a node at first it to linklist
7171 addFirst ( element ) {
7272 const node = new Node ( element )
73+ // Check if its the first element
74+ if ( this . headNode === null ) {
75+ this . tailNode = node
76+ }
77+ // Adding node at the start of the list and increase the length
7378 node . next = this . headNode
7479 this . headNode = node
7580 this . length ++
@@ -78,27 +83,36 @@ class LinkedList {
7883
7984 // remove the first from the linklist
8085 removeFirst ( ) {
86+ // Check if head is null
87+ if ( this . headNode === null ) {
88+ return null
89+ }
90+ // Removing node at the start of the list and decrease the length
8191 const removedNode = this . headNode
82- if ( this . length > 0 ) {
83- this . headNode = this . headNode . next
84- this . length --
92+ this . headNode = this . headNode . next
93+ this . length --
94+ // Check if the list is empty
95+ if ( this . isEmpty ( ) ) {
96+ this . tailNode = null
8597 }
8698 return removedNode ?. data
8799 }
88100
89101 // remove the last from the linklist
90102 removeLast ( ) {
91103 if ( this . isEmpty ( ) ) return null
104+ // Check if there is only one element
92105 if ( this . length === 1 ) {
93106 return this . removeFirst ( )
94107 }
95- let { currentIndex, currentNode } = this . initiateNodeAndIndex ( )
96- while ( currentIndex !== this . length - 2 ) {
97- currentIndex ++
108+ // Removing node at the end of the list and decrease the length
109+ const removedNode = this . tailNode
110+ let { currentNode } = this . initiateNodeAndIndex ( )
111+ while ( currentNode . next . next ) {
98112 currentNode = currentNode . next
99113 }
100- const removedNode = currentNode . next
101114 currentNode . next = null
115+ this . tailNode = currentNode
102116 this . length --
103117 return removedNode . data
104118 }
@@ -112,13 +126,17 @@ class LinkedList {
112126 if ( currentNode . data === element ) {
113127 return this . removeFirst ( )
114128 }
129+ // Check if the tail node is the element to remove
130+ if ( this . tailNode . data === element ) {
131+ return this . removeLast ( )
132+ }
115133 // Check which node is the node to remove
116- while ( currentNode ? .next ) {
134+ while ( currentNode . next ) {
117135 if ( currentNode . next . data === element ) {
118136 removedNode = currentNode . next
119137 currentNode . next = currentNode . next . next
120138 this . length --
121- break
139+ return removedNode . data
122140 }
123141 currentNode = currentNode . next
124142 }
@@ -127,10 +145,9 @@ class LinkedList {
127145
128146 // Returns the index of the element passed as param otherwise -1
129147 indexOf ( element ) {
130- let { currentIndex , currentNode } = this . initiateNodeAndIndex ( )
131-
148+ if ( this . isEmpty ( ) ) return - 1
149+ let { currentNode , currentIndex } = this . initiateNodeAndIndex ( )
132150 while ( currentNode ) {
133- // Checking if the node is the element we are searching for
134151 if ( currentNode . data === element ) {
135152 return currentIndex
136153 }
@@ -185,7 +202,7 @@ class LinkedList {
185202 throw new RangeError ( 'Out of Range index' )
186203 }
187204 if ( index === 0 ) return this . removeFirst ( )
188- if ( index === this . length ) return this . removeLast ( )
205+ if ( index === this . length - 1 ) return this . removeLast ( )
189206
190207 let { currentIndex, currentNode } = this . initiateNodeAndIndex ( )
191208 while ( currentIndex !== index - 1 ) {
@@ -194,7 +211,6 @@ class LinkedList {
194211 }
195212 const removedNode = currentNode . next
196213 currentNode . next = currentNode . next . next
197- // Decrementing the length
198214 this . length --
199215 return removedNode . data
200216 }
@@ -215,6 +231,7 @@ class LinkedList {
215231 // make the linkedList Empty
216232 clean ( ) {
217233 this . headNode = null
234+ this . tailNode = null
218235 this . length = 0
219236 }
220237
@@ -226,34 +243,28 @@ class LinkedList {
226243 list . push ( currentNode . data )
227244 currentNode = currentNode . next
228245 }
229-
230246 return list
231247 }
232248
233249 // Method for Rotating a List to the right by k places
234250 rotateListRight ( k ) {
235- let i = 0
251+ if ( ! this . headNode ) return
236252 let current = this . headNode
237- while ( current ) {
238- i ++
253+ let tail = this . tailNode
254+ let count = 1
255+ while ( current . next ) {
256+ count ++
239257 current = current . next
240258 }
241- k %= i
242- current = this . headNode
243- let prev = null
244- while ( k -- ) {
245- if ( ! current || ! current . next ) {
246- return current
247- } else {
248- while ( current . next ) {
249- prev = current
250- current = current . next
251- }
252- prev . next = current . next
253- current . next = this . headNode
254- this . headNode = current
255- }
259+ current . next = this . headNode
260+ tail = current
261+ k %= count
262+ while ( count - k > 0 ) {
263+ tail = tail . next
264+ count --
256265 }
266+ this . headNode = tail . next
267+ tail . next = null
257268 }
258269
259270 // Method to iterate over the LinkedList
@@ -286,6 +297,7 @@ class LinkedList {
286297 prev = head
287298 head = next
288299 }
300+ this . tailNode = this . headNode
289301 this . headNode = prev
290302 } ;
291303}
0 commit comments