@@ -19,6 +19,16 @@ export default class LinkedList<T> {
19
19
return this . length === 0 ;
20
20
}
21
21
22
+ /**
23
+ * Remove all nodes from list. Constant Time O(1)
24
+ */
25
+ public empty ( ) : boolean {
26
+ this . head = null ;
27
+ this . tail = null ;
28
+ this . length = 0 ;
29
+ return true ;
30
+ }
31
+
22
32
public append ( value : T ) : boolean {
23
33
const newNode = new Node ( value ) ;
24
34
@@ -61,17 +71,11 @@ export default class LinkedList<T> {
61
71
return true ;
62
72
}
63
73
64
-
65
74
const newNode = new Node ( value ) ;
66
75
67
- let currentNode : Node < T > = this . head ;
68
-
69
- for ( let i = 0 ; i < atIndex - 1 ; ++ i ) {
70
- currentNode = currentNode . getNext ( ) ;
71
- }
72
-
73
- newNode . setNext ( currentNode . getNext ( ) ) ;
74
- currentNode . setNext ( newNode ) ;
76
+ let currentNode = this . _traverseToNode ( atIndex - 1 ) ;
77
+ newNode . setNext ( currentNode ?. getNext ( ) ) ;
78
+ currentNode ?. setNext ( newNode ) ;
75
79
76
80
++ this . length ;
77
81
@@ -86,22 +90,14 @@ export default class LinkedList<T> {
86
90
87
91
if ( index === 0 ) {
88
92
value = this . head . getValue ( ) ;
89
- this . head = this . head . getNext ( ) ;
93
+ this . head = this . head . getNext ( ) ; // Manipulate pointers to mark deleted Node for garbage collection
90
94
}
91
95
else {
92
- let currentNode = this . head ;
93
-
94
- for ( let i = 0 ; i < index ; ++ i ) { // Traverse linked list to find Node index-1
95
- if ( i === index - 1 ) {
96
- value = currentNode . getNext ( ) . getValue ( ) ; // Store Node value
97
- break ;
98
- }
99
- currentNode = currentNode . getNext ( ) ;
100
- }
101
- currentNode . setNext ( currentNode . getNext ( ) . getNext ( ) ) ; // Manipulate pointers to mark deleted Node for garbage collection
96
+ let leader = this . _traverseToNode ( index - 1 ) ;
97
+ value = leader ?. getNext ( ) . getValue ( ) ;
98
+ leader ?. setNext ( leader . getNext ( ) . getNext ( ) ) ; // Manipulate pointers to mark deleted Node for garbage collection
102
99
}
103
-
104
- -- this . length ; // Decrement length
100
+ -- this . length ; // Decrement length
105
101
106
102
return value ;
107
103
}
@@ -111,14 +107,8 @@ export default class LinkedList<T> {
111
107
if ( this . length === 0 || ! this . head || ! this . tail ) return null ; // Verify that list is not empty
112
108
if ( index === this . length - 1 ) return this . tail . getValue ( ) ; // Optimization when retrieving last element
113
109
114
- let currentNode = this . head ;
115
-
116
- for ( let i = 0 ; i <= index ; ++ i ) {
117
- if ( i === index ) return currentNode . getValue ( ) ;
118
- currentNode = currentNode . getNext ( ) ;
119
- }
120
-
121
- return null ;
110
+ let targetNode = this . _traverseToNode ( index ) ;
111
+ return targetNode ?. getValue ( ) || null ;
122
112
}
123
113
124
114
/**
@@ -139,22 +129,24 @@ export default class LinkedList<T> {
139
129
return null ;
140
130
}
141
131
142
- /**
143
- * Remove all nodes from list. Constant Time O(1)
144
- */
145
- public empty ( ) : boolean {
146
- this . head = null ;
147
- this . tail = null ;
148
- this . length = 0 ;
149
- return true ;
132
+ private _traverseToNode ( index : number ) : Node < T > | null {
133
+ if ( ! this . head ) return null ;
134
+
135
+ let currentNode = this . head ;
136
+
137
+ for ( let i = 0 ; i < index ; ++ i ) {
138
+ currentNode = currentNode . getNext ( ) ;
139
+ }
140
+
141
+ return currentNode ;
150
142
}
151
143
152
144
public toString ( nodesPerGroup ?: number ) : string {
153
145
if ( this . length === 0 || ! this . head ) {
154
146
return "" ;
155
147
}
156
148
157
- nodesPerGroup = nodesPerGroup ? nodesPerGroup : 8 ;
149
+ nodesPerGroup = nodesPerGroup ? nodesPerGroup : 6 ;
158
150
159
151
const LABEL_HEAD = 'HEAD' ;
160
152
const LABEL_TAIL = 'TAIL' ;
@@ -163,7 +155,7 @@ export default class LinkedList<T> {
163
155
let currentNode : Node < any > = this . head ;
164
156
165
157
for ( let i = 0 ; i < this . length ; ++ i ) {
166
- listAsString += `${ Array ( i % nodesPerGroup ) . fill ( '\t' ) . join ( '' ) } ${ i === 0 ? LABEL_HEAD : '–' } ${ currentNode } ${ i === this . length - 1 ? LABEL_TAIL : '' } \n` ;
158
+ listAsString += `${ Array ( i % nodesPerGroup ) . fill ( '\t' ) . join ( '' ) } ${ i === 0 ? LABEL_HEAD : i } ${ currentNode } ${ i === this . length - 1 ? LABEL_TAIL : '' } \n` ;
167
159
168
160
if ( currentNode . hasNext ( ) ) {
169
161
currentNode = currentNode . getNext ( ) ;
@@ -249,16 +241,16 @@ if (import.meta.main) {
249
241
// --------------------------- Terminal Output: ---------------------------
250
242
// --- Node Count: 3
251
243
// HEAD { value: "Appa", next: true }
252
- // – { value: "Sokka", next: true }
253
- // – { value: "Katara", next: false } TAIL
254
- //
244
+ // 1 { value: "Sokka", next: true }
245
+ // 2 { value: "Katara", next: false } TAIL
246
+
255
247
// --- Node Count: 6
256
248
// HEAD { value: "Appa", next: true }
257
- // – { value: "Zuko", next: true }
258
- // – { value: "Sokka", next: true }
259
- // – { value: "Aang", next: true }
260
- // – { value: "Iroh", next: true }
261
- // – { value: "Katara", next: false } TAIL
249
+ // 1 { value: "Zuko", next: true }
250
+ // 2 { value: "Sokka", next: true }
251
+ // 3 { value: "Aang", next: true }
252
+ // 4 { value: "Iroh", next: true }
253
+ // 5 { value: "Katara", next: false } TAIL
262
254
//
263
255
// "Iroh" found at index: 4
264
256
// "Sok" found at index: null
@@ -271,28 +263,28 @@ if (import.meta.main) {
271
263
// Removing element at index 1: "Zuko"
272
264
// --- Node Count: 5
273
265
// HEAD { value: "Appa", next: true }
274
- // – { value: "Sokka", next: true }
275
- // – { value: "Aang", next: true }
276
- // – { value: "Iroh", next: true }
277
- // – { value: "Katara", next: false } TAIL
266
+ // 1 { value: "Sokka", next: true }
267
+ // 2 { value: "Aang", next: true }
268
+ // 3 { value: "Iroh", next: true }
269
+ // 4 { value: "Katara", next: false } TAIL
278
270
//
279
271
// Removing element at index 0: "Appa"
280
272
// --- Node Count: 4
281
273
// HEAD { value: "Sokka", next: true }
282
- // – { value: "Aang", next: true }
283
- // – { value: "Iroh", next: true }
284
- // – { value: "Katara", next: false } TAIL
274
+ // 1 { value: "Aang", next: true }
275
+ // 2 { value: "Iroh", next: true }
276
+ // 3 { value: "Katara", next: false } TAIL
285
277
//
286
278
// Removing element at index 2: "Iroh"
287
279
// --- Node Count: 3
288
280
// HEAD { value: "Sokka", next: true }
289
- // – { value: "Aang", next: true }
290
- // – { value: "Katara", next: false } TAIL
281
+ // 1 { value: "Aang", next: true }
282
+ // 2 { value: "Katara", next: false } TAIL
291
283
//
292
284
// Removing element at index 2: "Katara"
293
285
// --- Node Count: 2
294
286
// HEAD { value: "Sokka", next: true }
295
- // – { value: "Aang", next: false } TAIL
287
+ // 1 { value: "Aang", next: false } TAIL
296
288
//
297
289
// Removing element at index 1: "Aang"
298
290
// Removing element at index 0: "Sokka"
@@ -303,4 +295,4 @@ if (import.meta.main) {
303
295
//
304
296
// --- Node Count: 2
305
297
// HEAD { value: "Katara", next: true }
306
- // – { value: "Aang", next: false } TAIL
298
+ // 1 { value: "Aang", next: false } TAIL
0 commit comments