Inserting, removing, accessing, modifying, by index, on linked list with tests

This commit is contained in:
Yair Temkin 2022-01-28 15:26:39 -05:00
parent 819f38f792
commit 3303051d75
2 changed files with 150 additions and 14 deletions

View File

@ -87,6 +87,28 @@ export default class LinkedList {
}
return this;
}
/**
* @param {*} value
* @param {number} index
* @return {LinkedList}
*/
setAtIndex(value, index) {
if (index < 0) {
return this;
} else {
let count = 0;
let currentNode = this.head;
while (currentNode) {
if (count === index) break;
currentNode = currentNode.next;
count += 1;
}
if (currentNode) {
currentNode.value = value;
}
return this;
}
}
/**
* @param {*} value
@ -128,6 +150,36 @@ export default class LinkedList {
return deletedNode;
}
/**
* @param {number} index
* @return {LinkedListNode}
*/
deleteAtIndex(index) {
if (!this.head || index < 0) {
return null;
}
let deletedNode = null;
if (index === 0) {
deletedNode = this.head;
this.head = this.head.next;
} else {
let count = 1;
let currentNode = this.head;
while (currentNode) {
if (count === index) break;
currentNode = currentNode.next;
count += 1;
}
if (currentNode) {
deletedNode = currentNode.next;
if (deletedNode) {
currentNode.next = deletedNode.next;
}
}
}
return deletedNode;
}
/**
* @param {Object} findParams
* @param {*} findParams.value
@ -158,6 +210,26 @@ export default class LinkedList {
return null;
}
/**
* @param {*} index
* @return {LinkedListNode}
*/
findByIndex(index) {
if (!this.head || index < 0) {
return null;
} else if (index === 0) {
return this.head;
}
let count = 0;
let currentNode = this.head;
while (currentNode) {
if (count === index) break;
currentNode = currentNode.next;
count += 1;
}
return currentNode;
}
/**
* @return {LinkedListNode}
*/
@ -239,7 +311,9 @@ export default class LinkedList {
* @return {string}
*/
toString(callback) {
return this.toArray().map((node) => node.toString(callback)).toString();
return this.toArray()
.map((node) => node.toString(callback))
.toString();
}
/**

View File

@ -47,6 +47,26 @@ describe('LinkedList', () => {
expect(linkedList.toString()).toBe('1,4,2,3,10');
});
it('should insert node to linked list', () => {
const linkedList = new LinkedList();
linkedList.append(1).append(2).append(3).append(4).append(5);
expect(linkedList.toString()).toBe('1,2,3,4,5');
linkedList.setAtIndex(5, -2);
expect(linkedList.toString()).toBe('1,2,3,4,5');
linkedList.setAtIndex(12, 3);
expect(linkedList.toString()).toBe('1,2,3,12,5');
linkedList.setAtIndex(55, 0);
expect(linkedList.toString()).toBe('55,2,3,12,5');
linkedList.setAtIndex(0, 55);
expect(linkedList.toString()).toBe('55,2,3,12,5');
});
it('should delete node by value from linked list', () => {
const linkedList = new LinkedList();
@ -93,6 +113,34 @@ describe('LinkedList', () => {
expect(linkedList.toString()).toBe('');
});
it('should delete node at index from linked list', () => {
const linkedList = new LinkedList();
expect(linkedList.delete(5)).toBeNull();
linkedList.append(1);
linkedList.append(2);
linkedList.append(3);
linkedList.append(4);
linkedList.append(5);
expect(linkedList.head.toString()).toBe('1');
expect(linkedList.tail.toString()).toBe('5');
let deletedNode = linkedList.deleteAtIndex(3);
expect(deletedNode.value).toBe(4);
expect(linkedList.toString()).toBe('1,2,3,5');
linkedList.deleteAtIndex(1);
expect(linkedList.toString()).toBe('1,3,5');
deletedNode = linkedList.delete(-5);
expect(deletedNode).toBeNull();
deletedNode = linkedList.delete(10);
expect(deletedNode).toBeNull();
});
it('should delete linked list tail', () => {
const linkedList = new LinkedList();
@ -157,9 +205,7 @@ describe('LinkedList', () => {
const nodeValue1 = { value: 1, key: 'key1' };
const nodeValue2 = { value: 2, key: 'key2' };
linkedList
.append(nodeValue1)
.prepend(nodeValue2);
linkedList.append(nodeValue1).prepend(nodeValue2);
const nodeStringifier = (value) => `${value.key}:${value.value}`;
@ -174,9 +220,7 @@ describe('LinkedList', () => {
linkedList.append(1);
expect(linkedList.find({ value: 1 })).toBeDefined();
linkedList
.append(2)
.append(3);
linkedList.append(2).append(3);
const node = linkedList.find({ value: 2 });
@ -184,6 +228,21 @@ describe('LinkedList', () => {
expect(linkedList.find({ value: 5 })).toBeNull();
});
it('should find node by index', () => {
const linkedList = new LinkedList();
expect(linkedList.findByIndex(5)).toBeNull();
linkedList.append(1);
expect(linkedList.findByIndex(0).value).toBe(1);
linkedList.append(2).append(3);
const node = linkedList.findByIndex(2);
expect(node.value).toBe(3);
expect(linkedList.findByIndex(5)).toBeNull();
expect(linkedList.findByIndex(-3)).toBeNull();
});
it('should find node by callback', () => {
const linkedList = new LinkedList();
@ -192,12 +251,16 @@ describe('LinkedList', () => {
.append({ value: 2, key: 'test2' })
.append({ value: 3, key: 'test3' });
const node = linkedList.find({ callback: (value) => value.key === 'test2' });
const node = linkedList.find({
callback: (value) => value.key === 'test2',
});
expect(node).toBeDefined();
expect(node.value.value).toBe(2);
expect(node.value.key).toBe('test2');
expect(linkedList.find({ callback: (value) => value.key === 'test5' })).toBeNull();
expect(
linkedList.find({ callback: (value) => value.key === 'test5' })
).toBeNull();
});
it('should create linked list from array', () => {
@ -230,7 +293,9 @@ describe('LinkedList', () => {
expect(node).toBeDefined();
expect(node.value.value).toBe(2);
expect(node.value.customValue).toBe('test2');
expect(linkedList.find({ value: { value: 2, customValue: 'test5' } })).toBeNull();
expect(
linkedList.find({ value: { value: 2, customValue: 'test5' } })
).toBeNull();
});
it('should find preferring callback over compare function', () => {
@ -258,10 +323,7 @@ describe('LinkedList', () => {
const linkedList = new LinkedList();
// Add test values to linked list.
linkedList
.append(1)
.append(2)
.append(3);
linkedList.append(1).append(2).append(3);
expect(linkedList.toString()).toBe('1,2,3');
expect(linkedList.head.value).toBe(1);