mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2026-03-13 08:51:02 +08:00
Add Queue.
This commit is contained in:
@@ -3,28 +3,7 @@ import LinkedListNode from './LinkedListNode';
|
||||
export default class LinkedList {
|
||||
constructor() {
|
||||
this.head = null;
|
||||
}
|
||||
|
||||
append({ value, key = null }) {
|
||||
const newNode = new LinkedListNode({ value, key });
|
||||
|
||||
// If there is no head yet let's make new node a head.
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
// Rewind to last node.
|
||||
let currentNode = this.head;
|
||||
while (currentNode.next !== null) {
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
// Attach new node to the end of linked list.
|
||||
currentNode.next = newNode;
|
||||
|
||||
return newNode;
|
||||
this.tail = null;
|
||||
}
|
||||
|
||||
prepend({ value, key = null }) {
|
||||
@@ -36,12 +15,31 @@ export default class LinkedList {
|
||||
return newNode;
|
||||
}
|
||||
|
||||
append({ value, key = null }) {
|
||||
const newNode = new LinkedListNode({ value, key });
|
||||
|
||||
// If there is no head yet let's make new node a head.
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
this.tail = newNode;
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
// Attach new node to the end of linked list.
|
||||
this.tail.next = newNode;
|
||||
this.tail = newNode;
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
appendUnique({ value, key = null }) {
|
||||
const newNode = new LinkedListNode({ value, key });
|
||||
|
||||
// If there is no head yet let's make new node a head.
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
this.tail = newNode;
|
||||
|
||||
return newNode;
|
||||
}
|
||||
@@ -66,6 +64,7 @@ export default class LinkedList {
|
||||
|
||||
// Attach new node to the end of linked list.
|
||||
currentNode.next = newNode;
|
||||
this.tail = newNode;
|
||||
|
||||
return newNode;
|
||||
}
|
||||
@@ -90,8 +89,14 @@ export default class LinkedList {
|
||||
if (currentNode.next.value === value) {
|
||||
deletedNode = currentNode.next;
|
||||
currentNode.next = currentNode.next.next;
|
||||
} else {
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
// Check if tail must be deleted.
|
||||
if (this.tail.value === value) {
|
||||
this.tail = currentNode;
|
||||
}
|
||||
|
||||
return deletedNode;
|
||||
@@ -117,13 +122,44 @@ export default class LinkedList {
|
||||
if (currentNode.next.key === key) {
|
||||
deletedNode = currentNode.next;
|
||||
currentNode.next = currentNode.next.next;
|
||||
} else {
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
|
||||
// Check if tail must be deleted.
|
||||
if (this.tail.key === key) {
|
||||
this.tail = currentNode;
|
||||
}
|
||||
|
||||
return deletedNode;
|
||||
}
|
||||
|
||||
deleteTail() {
|
||||
if (this.head === this.tail) {
|
||||
const deletedTail = this.tail;
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
|
||||
return deletedTail;
|
||||
}
|
||||
|
||||
const deletedTail = this.tail;
|
||||
|
||||
// Rewind to the last node and delete "next" link for the node before the last one.
|
||||
let currentNode = this.head;
|
||||
while (currentNode.next) {
|
||||
if (!currentNode.next.next) {
|
||||
currentNode.next = null;
|
||||
} else {
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
}
|
||||
|
||||
this.tail = currentNode;
|
||||
return deletedTail;
|
||||
}
|
||||
|
||||
findByKey(key) {
|
||||
let currentNode = this.head;
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ describe('LinkedList', () => {
|
||||
it('should append node to linked list', () => {
|
||||
const linkedList = new LinkedList();
|
||||
|
||||
expect(linkedList.head).toBeNull();
|
||||
expect(linkedList.tail).toBeNull();
|
||||
|
||||
const node1 = linkedList.append({ value: 1 });
|
||||
const node2 = linkedList.append({ value: 2, key: 'test' });
|
||||
|
||||
@@ -16,6 +19,9 @@ describe('LinkedList', () => {
|
||||
expect(node2.value).toBe(2);
|
||||
expect(node2.key).toBe('test');
|
||||
|
||||
expect(linkedList.head.toString()).toBe('1');
|
||||
expect(linkedList.tail.toString()).toBe('test:2');
|
||||
|
||||
expect(linkedList.toString()).toBe('1,test:2');
|
||||
});
|
||||
|
||||
@@ -28,6 +34,9 @@ describe('LinkedList', () => {
|
||||
expect(node1.value).toBe(1);
|
||||
expect(node2.value).toBe(2);
|
||||
|
||||
expect(linkedList.head.toString()).toBe('2');
|
||||
expect(linkedList.tail.toString()).toBe('1');
|
||||
|
||||
expect(linkedList.toString()).toBe('2,1');
|
||||
});
|
||||
|
||||
@@ -38,18 +47,61 @@ describe('LinkedList', () => {
|
||||
linkedList.append({ value: 2 });
|
||||
linkedList.append({ value: 3 });
|
||||
linkedList.append({ value: 3 });
|
||||
linkedList.append({ value: 3 });
|
||||
linkedList.append({ value: 4 });
|
||||
linkedList.append({ value: 5 });
|
||||
|
||||
expect(linkedList.head.toString()).toBe('1');
|
||||
expect(linkedList.tail.toString()).toBe('5');
|
||||
|
||||
const deletedNode = linkedList.deleteByValue(3);
|
||||
expect(deletedNode.value).toBe(3);
|
||||
expect(linkedList.toString()).toBe('1,2,3,4,5');
|
||||
expect(linkedList.toString()).toBe('1,2,4,5');
|
||||
|
||||
linkedList.deleteByValue(3);
|
||||
expect(linkedList.toString()).toBe('1,2,4,5');
|
||||
|
||||
linkedList.deleteByValue(1);
|
||||
expect(linkedList.toString()).toBe('2,4,5');
|
||||
|
||||
expect(linkedList.head.toString()).toBe('2');
|
||||
expect(linkedList.tail.toString()).toBe('5');
|
||||
|
||||
linkedList.deleteByValue(5);
|
||||
expect(linkedList.toString()).toBe('2,4');
|
||||
|
||||
expect(linkedList.head.toString()).toBe('2');
|
||||
expect(linkedList.tail.toString()).toBe('4');
|
||||
|
||||
linkedList.deleteByValue(4);
|
||||
expect(linkedList.toString()).toBe('2');
|
||||
|
||||
expect(linkedList.head.toString()).toBe('2');
|
||||
expect(linkedList.tail.toString()).toBe('2');
|
||||
});
|
||||
|
||||
it('should delete linked list tail', () => {
|
||||
const linkedList = new LinkedList();
|
||||
|
||||
linkedList.append({ value: 1 });
|
||||
linkedList.append({ value: 2 });
|
||||
|
||||
expect(linkedList.head.toString()).toBe('1');
|
||||
expect(linkedList.tail.toString()).toBe('2');
|
||||
|
||||
const deletedNode1 = linkedList.deleteTail();
|
||||
|
||||
expect(deletedNode1.value).toBe(2);
|
||||
expect(linkedList.toString()).toBe('1');
|
||||
expect(linkedList.head.toString()).toBe('1');
|
||||
expect(linkedList.tail.toString()).toBe('1');
|
||||
|
||||
const deletedNode2 = linkedList.deleteTail();
|
||||
|
||||
expect(deletedNode2.value).toBe(1);
|
||||
expect(linkedList.toString()).toBe('');
|
||||
expect(linkedList.head).toBeNull();
|
||||
expect(linkedList.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should delete node by key from linked list', () => {
|
||||
|
||||
Reference in New Issue
Block a user