diff --git a/src/data-structures/graph/GraphVertex.js b/src/data-structures/graph/GraphVertex.js index 34be0fc5..7389e6e6 100644 --- a/src/data-structures/graph/GraphVertex.js +++ b/src/data-structures/graph/GraphVertex.js @@ -9,10 +9,22 @@ export default class GraphVertex { throw new Error('Graph vertex must have a value'); } + /** + * @param {GraphEdge} edgeA + * @param {GraphEdge} edgeB + */ + const edgeComparator = (edgeA, edgeB) => { + if (edgeA.getKey() === edgeB.getKey()) { + return 0; + } + + return edgeA.getKey() < edgeB.getKey() ? -1 : 1; + }; + // Normally you would store string value like vertex name. // But generally it may be any object as well this.value = value; - this.edges = new LinkedList(); + this.edges = new LinkedList(edgeComparator); } /** @@ -25,6 +37,13 @@ export default class GraphVertex { return this; } + /** + * @param {GraphEdge} edge + */ + deleteEdge(edge) { + this.edges.delete(edge); + } + /** * @returns {GraphVertex[]} */ diff --git a/src/data-structures/graph/__test__/GraphVertex.test.js b/src/data-structures/graph/__test__/GraphVertex.test.js index 8512c34d..1610e377 100644 --- a/src/data-structures/graph/__test__/GraphVertex.test.js +++ b/src/data-structures/graph/__test__/GraphVertex.test.js @@ -37,6 +37,39 @@ describe('GraphVertex', () => { expect(vertexA.getEdges()[0].toString()).toBe('A_B'); }); + it('should delete edges from vertex', () => { + const vertexA = new GraphVertex('A'); + const vertexB = new GraphVertex('B'); + const vertexC = new GraphVertex('C'); + + const edgeAB = new GraphEdge(vertexA, vertexB); + const edgeAC = new GraphEdge(vertexA, vertexC); + vertexA + .addEdge(edgeAB) + .addEdge(edgeAC); + + expect(vertexA.hasEdge(edgeAB)).toBeTruthy(); + expect(vertexB.hasEdge(edgeAB)).toBeFalsy(); + + expect(vertexA.hasEdge(edgeAC)).toBeTruthy(); + expect(vertexC.hasEdge(edgeAC)).toBeFalsy(); + + expect(vertexA.getEdges().length).toBe(2); + + expect(vertexA.getEdges()[0].toString()).toBe('A_B'); + expect(vertexA.getEdges()[1].toString()).toBe('A_C'); + + vertexA.deleteEdge(edgeAB); + expect(vertexA.hasEdge(edgeAB)).toBeFalsy(); + expect(vertexA.hasEdge(edgeAC)).toBeTruthy(); + expect(vertexA.getEdges()[0].toString()).toBe('A_C'); + + vertexA.deleteEdge(edgeAC); + expect(vertexA.hasEdge(edgeAB)).toBeFalsy(); + expect(vertexA.hasEdge(edgeAC)).toBeFalsy(); + expect(vertexA.getEdges().length).toBe(0); + }); + it('should return vertex neighbors in case if current node is start one', () => { const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); diff --git a/src/data-structures/linked-list/LinkedList.js b/src/data-structures/linked-list/LinkedList.js index 0835d85a..b428ad73 100644 --- a/src/data-structures/linked-list/LinkedList.js +++ b/src/data-structures/linked-list/LinkedList.js @@ -67,13 +67,15 @@ export default class LinkedList { let currentNode = this.head; - // If next node must be deleted then make next node to be a next next one. - while (currentNode.next) { - if (this.compare.equal(currentNode.next.value, value)) { - deletedNode = currentNode.next; - currentNode.next = currentNode.next.next; - } else { - currentNode = currentNode.next; + if (currentNode !== null) { + // If next node must be deleted then make next node to be a next next one. + while (currentNode.next) { + if (this.compare.equal(currentNode.next.value, value)) { + deletedNode = currentNode.next; + currentNode.next = currentNode.next.next; + } else { + currentNode = currentNode.next; + } } } diff --git a/src/data-structures/linked-list/__test__/LinkedList.test.js b/src/data-structures/linked-list/__test__/LinkedList.test.js index e400a0ea..1b938e1b 100644 --- a/src/data-structures/linked-list/__test__/LinkedList.test.js +++ b/src/data-structures/linked-list/__test__/LinkedList.test.js @@ -67,6 +67,9 @@ describe('LinkedList', () => { expect(linkedList.head.toString()).toBe('2'); expect(linkedList.tail.toString()).toBe('2'); + + linkedList.delete(2); + expect(linkedList.toString()).toBe(''); }); it('should delete linked list tail', () => {