forked from andrewrjones/doubly-linked-list-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoubly-linked-list.js
171 lines (138 loc) · 3.37 KB
/
doubly-linked-list.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
(function (exports) {
"use strict";
/*
* Constructor. Takes no arguments.
*/
function DoublyLinkedList() {
// pointer to first item
this._head = null;
// pointer to the last item
this._tail = null;
// length of list
this._length = 0;
}
// Wraps data in a node object.
DoublyLinkedList.prototype._createNewNode = function (data) {
var list = this;
var node = {
data: data,
next: null,
prev: null,
remove: function() {
if (this.prev !== null) {
this.prev.next = this.next;
}
if (this.next !== null) {
this.next.prev = this.prev;
}
if (list._head === this) {
list._head = this.next;
}
if (list._tail === this) {
list._tail = this.prev;
}
list._length--;
},
prepend: function(data) {
if (list._head === this) {
return list.prepend(data);
}
var newNode = list._createNewNode(data);
newNode.prev = this.prev;
newNode.next = this;
this.prev.next = newNode;
this.prev = newNode;
list._length++;
return newNode;
},
append: function(data) {
if (list._tail === this) {
return list.append(data);
}
var newNode = list._createNewNode(data);
newNode.prev = this;
newNode.next = this.next;
this.next.prev = newNode;
this.next = newNode;
list._length++;
return newNode;
}
};
return node;
};
/*
* Appends a node to the end of the list.
*/
DoublyLinkedList.prototype.append = function (data) {
var node = this._createNewNode(data);
if (this._length === 0) {
// first node, so all pointers to this
this._head = node;
this._tail = node;
} else {
// put on the tail
this._tail.next = node;
node.prev = this._tail;
this._tail = node;
}
// update count
this._length++;
return node;
};
/*
* Prepends a node to the end of the list.
*/
DoublyLinkedList.prototype.prepend = function (data) {
var node = this._createNewNode(data);
if (this._head === null) {
// we are empty, so this is the first node
// use the same logic as append
return this.append(data);
} else {
// place before head
this._head.prev = node;
node.next = this._head;
this._head = node;
}
// update count
this._length++;
return node;
};
/*
* Returns the node at the specified index. The index starts at 0.
*/
DoublyLinkedList.prototype.item = function (index) {
if (index >= 0 && index < this._length) {
var node = this._head;
while (index--) {
node = node.next;
}
return node;
}
};
/*
* Returns the node at the head of the list.
*/
DoublyLinkedList.prototype.head = function () {
return this._head;
};
/*
* Returns the node at the tail of the list.
*/
DoublyLinkedList.prototype.tail = function () {
return this._tail;
};
/*
* Returns the size of the list.
*/
DoublyLinkedList.prototype.size = function () {
return this._length;
};
/*
* Removes the item at the index.
*/
DoublyLinkedList.prototype.remove = function (index) {
throw "Not implemented";
};
exports.DoublyLinkedList = DoublyLinkedList;
})(typeof exports === 'undefined' ? this['DLL'] = {} : exports);