1
+ let DoublyLinkedList2 = ( function ( ) {
2
+
3
+ class Node {
4
+ constructor ( element ) {
5
+ this . element = element ;
6
+ this . next = null ;
7
+ this . prev = null ; //NEW
8
+ }
9
+ }
10
+
11
+ const length = new WeakMap ( ) ;
12
+ const head = new WeakMap ( ) ;
13
+ const tail = new WeakMap ( ) ; //NEW
14
+
15
+ class DoublyLinkedList2 {
16
+
17
+ constructor ( ) {
18
+ length . set ( this , 0 ) ;
19
+ head . set ( this , null ) ;
20
+ tail . set ( this , null ) ;
21
+ }
22
+
23
+ append = function ( element ) {
24
+
25
+ let node = new Node ( element ) ,
26
+ current , _tail ;
27
+
28
+ if ( this . getHead ( ) === null ) { //first node on list
29
+ head . set ( this , node ) ;
30
+ tail . set ( this , node ) ; //NEW
31
+ } else {
32
+ //attach to the tail node //NEW
33
+ _tail = this . getTail ( ) ;
34
+ _tail . next = node ;
35
+ node . prev = _tail ;
36
+ tail . set ( this , node ) ;
37
+ }
38
+
39
+ //update size of list
40
+ let l = this . size ( ) ;
41
+ l ++ ;
42
+ length . set ( this , l ) ;
43
+ }
44
+
45
+ insert = function ( position , element ) {
46
+
47
+ //check for out-of-bounds values
48
+ if ( position >= 0 && position <= this . size ( ) ) {
49
+
50
+ let node = new Node ( element ) ,
51
+ current = this . getHead ( ) ,
52
+ previous ,
53
+ index = 0 ;
54
+
55
+ if ( position === 0 ) { //add on first position
56
+
57
+ if ( ! this . getHead ( ) ) { //NEW
58
+ head . set ( this , node ) ;
59
+ tail . set ( this , node ) ;
60
+ } else {
61
+ node . next = current ;
62
+ current . prev = node ; //NEW {1}
63
+ head . set ( this , node ) ;
64
+ }
65
+
66
+ } else if ( position === this . size ( ) ) { //last item //NEW
67
+
68
+ current = tail ; // {2}
69
+ current . next = node ;
70
+ node . prev = current ;
71
+ tail . set ( this , node ) ;
72
+
73
+ } else {
74
+ while ( index ++ < position ) { //{3}
75
+ previous = current ;
76
+ current = current . next ;
77
+ }
78
+ node . next = current ;
79
+ previous . next = node ;
80
+
81
+ current . prev = node ; //NEW
82
+ node . prev = previous ; //NEW
83
+ }
84
+
85
+ //update size of list
86
+ let l = this . size ( ) ;
87
+ l ++ ;
88
+ length . set ( this , l ) ;
89
+
90
+ return true ;
91
+
92
+ } else {
93
+ return false ;
94
+ }
95
+ }
96
+
97
+ removeAt = function ( position ) {
98
+
99
+ //check for out-of-bounds values
100
+ if ( position > - 1 && position < this . size ( ) ) {
101
+
102
+ let _head = this . getHead ( ) ,
103
+ _tail = this . getTail ( ) ,
104
+ current = _head ,
105
+ previous ,
106
+ index = 0 ;
107
+
108
+ //removing first item
109
+ if ( position === 0 ) {
110
+
111
+ _head = current . next ; // {1}
112
+
113
+ //if there is only one item, then we update tail as well //NEW
114
+ if ( this . size ( ) === 1 ) { // {2}
115
+ _tail = null ;
116
+ } else {
117
+ _head . prev = null ; // {3}
118
+ }
119
+
120
+ } else if ( position === this . size ( ) - 1 ) { //last item //NEW
121
+
122
+ current = _tail ; // {4}
123
+ _tail = current . prev ;
124
+ _tail . next = null ;
125
+
126
+ } else {
127
+
128
+ while ( index ++ < position ) { // {5}
129
+
130
+ previous = current ;
131
+ current = current . next ;
132
+ }
133
+
134
+ //link previous with current's next - skip it to remove
135
+ previous . next = current . next ; // {6}
136
+ current . next . prev = previous ; //NEW
137
+ }
138
+
139
+ head . set ( this , _head ) ;
140
+ tail . set ( this , _tail ) ;
141
+
142
+ //update size of list
143
+ let l = this . size ( ) ;
144
+ l -- ;
145
+ length . set ( this , l ) ;
146
+
147
+ return current . element ;
148
+
149
+ } else {
150
+ return null ;
151
+ }
152
+ }
153
+
154
+ remove = function ( element ) {
155
+
156
+ let index = this . indexOf ( element ) ;
157
+ return this . removeAt ( index ) ;
158
+ }
159
+
160
+ indexOf = function ( element ) {
161
+
162
+ let current = this . getHead ( ) ,
163
+ index = - 1 ;
164
+
165
+ //check first item
166
+ if ( element == current . element ) {
167
+ return 0 ;
168
+ }
169
+
170
+ index ++ ;
171
+
172
+ //check in the middle of the list
173
+ while ( current . next ) {
174
+
175
+ if ( element == current . element ) {
176
+ return index ;
177
+ }
178
+
179
+ current = current . next ;
180
+ index ++ ;
181
+ }
182
+
183
+ //check last item
184
+ if ( element == current . element ) {
185
+ return index ;
186
+ }
187
+
188
+ return - 1 ;
189
+ }
190
+
191
+ isEmpty ( ) {
192
+ return this . size ( ) === 0 ;
193
+ }
194
+
195
+ size ( ) {
196
+ return length . get ( this ) ;
197
+ }
198
+
199
+ toString = function ( ) {
200
+
201
+ let current = this . getHead ( ) ,
202
+ s = current ? current . element : '' ;
203
+
204
+ while ( current && current . next ) {
205
+ current = current . next ;
206
+ s += ', ' + current . element ;
207
+ }
208
+
209
+ return s ;
210
+ }
211
+
212
+ inverseToString = function ( ) {
213
+
214
+ let current = this . getTail ( ) ,
215
+ s = current ? current . element : '' ;
216
+
217
+ while ( current && current . prev ) {
218
+ current = current . prev ;
219
+ s += ', ' + current . element ;
220
+ }
221
+
222
+ return s ;
223
+ }
224
+
225
+ print = function ( ) {
226
+ console . log ( this . toString ( ) ) ;
227
+ }
228
+
229
+ printInverse = function ( ) {
230
+ console . log ( this . inverseToString ( ) ) ;
231
+ }
232
+
233
+ getHead ( ) {
234
+ return head . get ( this ) ;
235
+ }
236
+
237
+ getTail = function ( ) {
238
+ return tail . get ( this ) ;
239
+ }
240
+ }
241
+ return DoublyLinkedList2 ;
242
+ } ) ( ) ;
0 commit comments