Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4989a6a

Browse files
hanhdttrekhleb
authored andcommitted
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‎

Lines changed: 62 additions & 0 deletions
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‎

Lines changed: 5 additions & 5 deletions
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‎

Lines changed: 37 additions & 0 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /