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