1
+ // https://en.wikipedia.org/wiki/Doubly_linked_list
2
+
3
+ function Node ( data ) {
4
+ this . data = data
5
+ this . next = null
6
+ this . prev = null
7
+ }
8
+
9
+ function DoublyLinkedList ( ) {
10
+ this . length = 0
11
+ this . head = null
12
+ this . tail = null
13
+ }
14
+
15
+ DoublyLinkedList . prototype . add = function ( value ) {
16
+ let node = new Node ( value )
17
+
18
+ node . next = this . head
19
+ if ( this . head ) {
20
+ this . head . prev = node
21
+ } else {
22
+ this . tail = node
23
+ }
24
+ this . length ++
25
+ this . head = node
26
+ node . prev = null
27
+ }
28
+
29
+ DoublyLinkedList . prototype . remove = function ( position ) {
30
+ let toRemove = this . findAt ( position )
31
+
32
+ if ( ! toRemove ) return null
33
+
34
+ if ( toRemove === this . head ) {
35
+ this . head = toRemove . next
36
+ if ( ! this . head ) {
37
+ this . tail = null
38
+ } else {
39
+ this . head . prev = null
40
+ }
41
+ } else if ( toRemove === this . tail ) {
42
+ toRemove . prev . next = null
43
+ this . tail = toRemove . prev
44
+ } else {
45
+ toRemove . prev . next = toRemove . next
46
+ toRemove . next . prev = toRemove . prev
47
+ }
48
+
49
+ this . length --
50
+ return toRemove
51
+ }
52
+
53
+ DoublyLinkedList . prototype . findAt = function ( position ) {
54
+ if ( position > - 1 && position < this . length ) {
55
+ let current = this . head
56
+
57
+ for ( let i = 0 ; i ++ < position ; current = current . next ) ;
58
+
59
+ return current
60
+ }
61
+ return null
62
+ }
63
+
64
+ const test = require ( 'tape' )
65
+
66
+ test ( 'Doubly linked list add' , assert => {
67
+ let dl = new DoublyLinkedList ( )
68
+ dl . add ( 'Hello world!' )
69
+ assert . deepEqual ( dl . head . data , 'Hello world!' )
70
+ assert . deepEqual ( dl . length , 1 )
71
+
72
+ dl . add ( 'Can you see me?' )
73
+ assert . deepEqual ( dl . length , 2 )
74
+ assert . deepEqual ( dl . tail . data , 'Hello world!' )
75
+ assert . end ( )
76
+ } )
77
+
78
+ test ( 'Doubly linked list findAt' , assert => {
79
+ let dl = new DoublyLinkedList ( )
80
+ dl . add ( 'Hello world!' )
81
+ dl . add ( 'Can you see me?' )
82
+ dl . add ( 'Now you don\'t' )
83
+ assert . deepEqual ( dl . findAt ( 0 ) . data , 'Now you don\'t' )
84
+ assert . deepEqual ( dl . findAt ( 2 ) . data , 'Hello world!' )
85
+ assert . deepEqual ( dl . findAt ( 3 ) , null )
86
+ assert . end ( )
87
+ } )
88
+
89
+ test ( 'Doubly linked list remove' , assert => {
90
+ let dl = new DoublyLinkedList ( )
91
+ dl . add ( 'Hello world!' )
92
+ dl . add ( 'Can you see me?' )
93
+ dl . add ( 'Now you don\'t' )
94
+ let removed = dl . remove ( 2 )
95
+ assert . deepEqual ( dl . tail . data , 'Can you see me?' )
96
+ assert . deepEqual ( removed . data , 'Hello world!' )
97
+ assert . deepEqual ( 2 , dl . length )
98
+ dl . remove ( 1 )
99
+ assert . deepEqual ( 1 , dl . length )
100
+ removed = dl . remove ( 0 )
101
+ assert . deepEqual ( removed . data , 'Now you don\'t' )
102
+ assert . end ( )
103
+ } )
0 commit comments