Skip to content

Commit 4989a6a

Browse files
hanhdttrekhleb
authored andcommittedSep 8, 2018
Add LinkedList traversal and reverse implementations (trekhleb#194)
* Add LinkedList traverse function * Add LinkedList reverse traversal implementations * Update LinkedList traverse function * Update LinkedList reverse traversal and test cases * Update LinkedList traversal tests
1 parent d038c40 commit 4989a6a

File tree

3 files changed

+104
-5
lines changed

3 files changed

+104
-5
lines changed
 

‎src/data-structures/linked-list/LinkedList.js

+62
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,66 @@ export default class LinkedList {
207207
toString(callback) {
208208
return this.toArray().map(node => node.toString(callback)).toString();
209209
}
210+
211+
/**
212+
* Traverse through all nodes of the list from head to tail
213+
* @param {*} callback
214+
* @return {LinkedListNode[]}
215+
*/
216+
traverse(callback = undefined) {
217+
if (typeof callback !== 'function') {
218+
throw new TypeError(`traverse method requires a callback function as an argument.\nArgument given: ${typeof callback}`);
219+
}
220+
221+
let currentNode = this.head;
222+
const traversedNodes = [];
223+
224+
while (currentNode) {
225+
traversedNodes.push(callback(currentNode.value));
226+
currentNode = currentNode.next;
227+
}
228+
229+
return traversedNodes;
230+
}
231+
232+
/**
233+
* The items in the list have been traversed in reverse order
234+
*/
235+
reverseTraversal(node, callback = undefined) {
236+
if (typeof callback !== 'function') {
237+
throw new TypeError(`reverseTraverse method requires a callback function as an argument.\nArgument given: ${typeof callback}`);
238+
}
239+
240+
if (!node) return [];
241+
242+
return this.reverseTraversal(node.next, callback).concat(callback(node.value));
243+
}
244+
245+
/**
246+
* Reverse a singly linked list use to three variables
247+
* @returns {ReservedLinkedList}
248+
*/
249+
reverse() {
250+
let currNode = this.head;
251+
let prevNode = null;
252+
let nextNode = null;
253+
254+
while (currNode) {
255+
// Store next node
256+
nextNode = currNode.next;
257+
258+
// Change next node of the current
259+
currNode.next = prevNode;
260+
261+
// Move forward prev and current nodes one step
262+
prevNode = currNode;
263+
currNode = nextNode;
264+
}
265+
266+
// Reset head, tail
267+
this.tail = this.head;
268+
this.head = prevNode;
269+
270+
return this;
271+
}
210272
}

‎src/data-structures/linked-list/README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,24 @@ Traverse(head)
110110
Pre: head is the head node in the list
111111
Post: the items in the list have been traversed
112112
n ← head
113-
while n = 0
113+
while n != ø
114114
yield n.value
115115
n ← n.next
116116
end while
117117
end Traverse
118118
```
119-
119+
120120
### Traverse in Reverse
121121

122122
```text
123123
ReverseTraversal(head, tail)
124124
Pre: head and tail belong to the same list
125125
Post: the items in the list have been traversed in reverse order
126-
if tail = ø
126+
if tail != ø
127127
curr ← tail
128-
while curr = head
128+
while curr != head
129129
prev ← head
130-
while prev.next = curr
130+
while prev.next != curr
131131
prev ← prev.next
132132
end while
133133
yield curr.value

‎src/data-structures/linked-list/__test__/LinkedList.test.js

+37
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,41 @@ describe('LinkedList', () => {
217217
expect(node.value.customValue).toBe('test2');
218218
expect(linkedList.find({ value: 2, customValue: 'test5' })).toBeNull();
219219
});
220+
221+
it('should traverse through all nodes of the list from head to tail with callback', () => {
222+
const linkedList = new LinkedList();
223+
224+
linkedList
225+
.append(1)
226+
.append(2)
227+
.append(3);
228+
229+
expect(linkedList.traverse(value => value * 2)).toEqual([2, 4, 6]);
230+
expect(() => linkedList.traverse()).toThrow();
231+
});
232+
233+
it('should reverse traversal the linked list with callback', () => {
234+
const linkedList = new LinkedList();
235+
236+
linkedList
237+
.append(1)
238+
.append(2)
239+
.append(3);
240+
241+
expect(linkedList.toString()).toBe('1,2,3');
242+
expect(linkedList.reverseTraversal(linkedList.head, value => value * 2)).toEqual([6, 4, 2]);
243+
expect(() => linkedList.reverseTraversal(linkedList.head)).toThrow();
244+
});
245+
246+
it('should reverse the singly linked list', () => {
247+
const linkedList = new LinkedList();
248+
249+
linkedList
250+
.append(1)
251+
.append(2)
252+
.append(3);
253+
254+
expect(linkedList.toString()).toBe('1,2,3');
255+
expect(linkedList.reverse().toString()).toBe('3,2,1');
256+
});
220257
});

0 commit comments

Comments
 (0)
Please sign in to comment.