mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-25 22:46:20 +08:00
Add LinkedList traversal and reverse implementations (#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
This commit is contained in:
parent
d038c402dd
commit
4989a6a3b0
@ -207,4 +207,66 @@ export default class LinkedList {
|
||||
toString(callback) {
|
||||
return this.toArray().map(node => node.toString(callback)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse through all nodes of the list from head to tail
|
||||
* @param {*} callback
|
||||
* @return {LinkedListNode[]}
|
||||
*/
|
||||
traverse(callback = undefined) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new TypeError(`traverse method requires a callback function as an argument.\nArgument given: ${typeof callback}`);
|
||||
}
|
||||
|
||||
let currentNode = this.head;
|
||||
const traversedNodes = [];
|
||||
|
||||
while (currentNode) {
|
||||
traversedNodes.push(callback(currentNode.value));
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
return traversedNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The items in the list have been traversed in reverse order
|
||||
*/
|
||||
reverseTraversal(node, callback = undefined) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new TypeError(`reverseTraverse method requires a callback function as an argument.\nArgument given: ${typeof callback}`);
|
||||
}
|
||||
|
||||
if (!node) return [];
|
||||
|
||||
return this.reverseTraversal(node.next, callback).concat(callback(node.value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse a singly linked list use to three variables
|
||||
* @returns {ReservedLinkedList}
|
||||
*/
|
||||
reverse() {
|
||||
let currNode = this.head;
|
||||
let prevNode = null;
|
||||
let nextNode = null;
|
||||
|
||||
while (currNode) {
|
||||
// Store next node
|
||||
nextNode = currNode.next;
|
||||
|
||||
// Change next node of the current
|
||||
currNode.next = prevNode;
|
||||
|
||||
// Move forward prev and current nodes one step
|
||||
prevNode = currNode;
|
||||
currNode = nextNode;
|
||||
}
|
||||
|
||||
// Reset head, tail
|
||||
this.tail = this.head;
|
||||
this.head = prevNode;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -110,24 +110,24 @@ Traverse(head)
|
||||
Pre: head is the head node in the list
|
||||
Post: the items in the list have been traversed
|
||||
n ← head
|
||||
while n = 0
|
||||
while n != ø
|
||||
yield n.value
|
||||
n ← n.next
|
||||
end while
|
||||
end Traverse
|
||||
```
|
||||
|
||||
|
||||
### Traverse in Reverse
|
||||
|
||||
```text
|
||||
ReverseTraversal(head, tail)
|
||||
Pre: head and tail belong to the same list
|
||||
Post: the items in the list have been traversed in reverse order
|
||||
if tail = ø
|
||||
if tail != ø
|
||||
curr ← tail
|
||||
while curr = head
|
||||
while curr != head
|
||||
prev ← head
|
||||
while prev.next = curr
|
||||
while prev.next != curr
|
||||
prev ← prev.next
|
||||
end while
|
||||
yield curr.value
|
||||
|
@ -217,4 +217,41 @@ describe('LinkedList', () => {
|
||||
expect(node.value.customValue).toBe('test2');
|
||||
expect(linkedList.find({ value: 2, customValue: 'test5' })).toBeNull();
|
||||
});
|
||||
|
||||
it('should traverse through all nodes of the list from head to tail with callback', () => {
|
||||
const linkedList = new LinkedList();
|
||||
|
||||
linkedList
|
||||
.append(1)
|
||||
.append(2)
|
||||
.append(3);
|
||||
|
||||
expect(linkedList.traverse(value => value * 2)).toEqual([2, 4, 6]);
|
||||
expect(() => linkedList.traverse()).toThrow();
|
||||
});
|
||||
|
||||
it('should reverse traversal the linked list with callback', () => {
|
||||
const linkedList = new LinkedList();
|
||||
|
||||
linkedList
|
||||
.append(1)
|
||||
.append(2)
|
||||
.append(3);
|
||||
|
||||
expect(linkedList.toString()).toBe('1,2,3');
|
||||
expect(linkedList.reverseTraversal(linkedList.head, value => value * 2)).toEqual([6, 4, 2]);
|
||||
expect(() => linkedList.reverseTraversal(linkedList.head)).toThrow();
|
||||
});
|
||||
|
||||
it('should reverse the singly linked list', () => {
|
||||
const linkedList = new LinkedList();
|
||||
|
||||
linkedList
|
||||
.append(1)
|
||||
.append(2)
|
||||
.append(3);
|
||||
|
||||
expect(linkedList.toString()).toBe('1,2,3');
|
||||
expect(linkedList.reverse().toString()).toBe('3,2,1');
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user