From dfe200a957f7c519fcaee1dd5c0f249ad7ae1bd1 Mon Sep 17 00:00:00 2001 From: Rahul Raj <43320722+rraj798@users.noreply.github.com> Date: Sat, 9 Apr 2022 12:26:22 +0530 Subject: [PATCH] merge: Improving coding standard of singly linked list (#980) * Auto-update DIRECTORY.md * Changes on SinglyLinkedList * Spelling change * Added comment for initiateNodeAndIndex() Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- .../Linked-List/SinglyLinkedList.js | 242 +++++++++--------- .../Linked-List/test/SinglyLinkedList.test.js | 53 ++-- 2 files changed, 153 insertions(+), 142 deletions(-) diff --git a/Data-Structures/Linked-List/SinglyLinkedList.js b/Data-Structures/Linked-List/SinglyLinkedList.js index ccf3557b4..378540c2c 100644 --- a/Data-Structures/Linked-List/SinglyLinkedList.js +++ b/Data-Structures/Linked-List/SinglyLinkedList.js @@ -6,7 +6,7 @@ * a singly linked list. */ -// Methods - size, head, addLast, addFirst, addAt, removeFirst, removeLast, remove, removeAt, indexOf, isEmpty, elementAt, get +// Methods - size, head, addLast, addFirst, addAt, removeFirst, removeLast, remove, removeAt, indexOf, isEmpty, elementAt, get, clean class Node { constructor (data) { @@ -21,6 +21,11 @@ class LinkedList { this.length = 0 } + // initiates the currentNode and currentIndex and return as an object + initiateNodeAndIndex () { + return { currentNode: this.headNode, currentIndex: 0 } + } + // Returns length size () { return this.length @@ -28,84 +33,7 @@ class LinkedList { // Returns the head head () { - return this.headNode ? this.headNode.data : null - } - - // add a node at last it to linklist - addLast (element) { - const node = new Node(element) - - // Check if its the first element - if (this.headNode === null) { - this.headNode = node - } else { - let currentNode = this.headNode - - // Loop till there is a node present in the list - while (currentNode.next) { - currentNode = currentNode.next - } - - // Adding node at the end of the list - currentNode.next = node - } - - this.length++ // Increment the length - } - - // add a node at first it to linklist - addFirst (element) { - const node = new Node(element) - node.next = this.headNode - this.headNode = node - this.length++ // Increment the length - } - - // remove the first from the linklist - removeFirst () { - if (this.length > 0) { - this.headNode = this.headNode.next - this.length-- - } - } - - // remove the last from the linklist - removeLast () { - if (this.length === 1) { - this.headNode = null - this.length-- - } else if (this.length > 1) { - let index = 0 - let currentNode = this.headNode - while (index !== this.length - 2) { - index++ - currentNode = currentNode.next - } - - currentNode.next = null - this.length-- - } - } - - // Removes the node with the value as param - remove (element) { - let currentNode = this.headNode - - // Check if the head node is the element to remove - if (currentNode.data === element) { - this.headNode = currentNode.next - } else { - // Check which node is the node to remove - while (currentNode && currentNode.next) { - if (currentNode.next.data === element) { - currentNode.next = currentNode.next.next - break - } - currentNode = currentNode.next - } - } - - this.length-- // Decrementing the length + return this.headNode?.data || null } // Return if the list is empty @@ -113,20 +41,97 @@ class LinkedList { return this.length === 0 } + // add a node at last it to linklist + addLast (element) { + // Check if its the first element + if (this.headNode === null) { + return this.addFirst(element) + } + let { currentNode } = this.initiateNodeAndIndex() + + // Loop till there is a node present in the list + while (currentNode.next) { + currentNode = currentNode.next + } + + const node = new Node(element) + // Adding node at the end of the list and increase the length + currentNode.next = node + this.length++ + return this.size() + } + + // add a node at first it to linklist + addFirst (element) { + const node = new Node(element) + node.next = this.headNode + this.headNode = node + this.length++ + return this.size() + } + + // remove the first from the linklist + removeFirst () { + const removedNode = this.headNode + if (this.length > 0) { + this.headNode = this.headNode.next + this.length-- + } + console.log(removedNode.data) + return removedNode?.data + } + + // remove the last from the linklist + removeLast () { + if (this.isEmpty()) return null + if (this.length === 1) { + return this.removeFirst() + } + let { currentIndex, currentNode } = this.initiateNodeAndIndex() + while (currentIndex !== this.length - 2) { + currentIndex++ + currentNode = currentNode.next + } + const removedNode = currentNode.next + currentNode.next = null + this.length-- + return removedNode.data + } + + // Removes the node with the value as param + remove (element) { + if (this.isEmpty()) return null + let { currentNode } = this.initiateNodeAndIndex() + let removedNode = null + // Check if the head node is the element to remove + if (currentNode.data === element) { + return this.removeFirst() + } + // Check which node is the node to remove + while (currentNode?.next) { + if (currentNode.next.data === element) { + removedNode = currentNode.next + currentNode.next = currentNode.next.next + this.length-- + break + } + currentNode = currentNode.next + } + return removedNode?.data || null + } + // Returns the index of the element passed as param otherwise -1 indexOf (element) { - let currentNode = this.headNode - let index = 0 + let { currentIndex, currentNode } = this.initiateNodeAndIndex() while (currentNode) { // Checking if the node is the element we are searching for if (currentNode.data === element) { - return index + return currentIndex } currentNode = currentNode.next - index++ + currentIndex++ } - return -1 } @@ -135,10 +140,9 @@ class LinkedList { if (index >= this.length || index < 0) { throw new RangeError('Out of Range index') } - let currentNode = this.headNode - let count = 0 - while (count < index) { - count++ + let { currentIndex, currentNode } = this.initiateNodeAndIndex() + while (currentIndex < index) { + currentIndex++ currentNode = currentNode.next } return currentNode.data @@ -146,64 +150,60 @@ class LinkedList { // Adds the element at specified index addAt (index, element) { - const node = new Node(element) - // Check if index is out of bounds of list if (index > this.length || index < 0) { throw new RangeError('Out of Range index') } + if (index === 0) return this.addFirst(element) + if (index === this.length) return this.addLast(element) + let { currentIndex, currentNode } = this.initiateNodeAndIndex() + const node = new Node(element) - let currentNode = this.headNode - let currentIndex = 0 - // Check if index is the start of list - if (index === 0) { - node.next = currentNode - this.headNode = node - } else { - while (currentIndex !== index - 1) { - currentIndex++ - currentNode = currentNode.next - } - - // Adding the node at specified index - const temp = currentNode.next - currentNode.next = node - node.next = temp + while (currentIndex !== index - 1) { + currentIndex++ + currentNode = currentNode.next } + // Adding the node at specified index + const tempNode = currentNode.next + currentNode.next = node + node.next = tempNode // Incrementing the length this.length++ + return this.size() } // Removes the node at specified index removeAt (index) { - let currentNode = this.headNode - let currentIndex = 0 - // Check if index is present in list if (index < 0 || index >= this.length) { throw new RangeError('Out of Range index') } + if (index === 0) return this.removeFirst() + if (index === this.length) return this.removeLast() - // Check if element is the first element - if (index === 0) { - this.headNode = currentNode.next - } else { - while (currentIndex !== index - 1) { - currentIndex++ - currentNode = currentNode.next - } - currentNode.next = currentNode.next.next + let { currentIndex, currentNode } = this.initiateNodeAndIndex() + while (currentIndex !== index - 1) { + currentIndex++ + currentNode = currentNode.next } - + const removedNode = currentNode.next + currentNode.next = currentNode.next.next // Decrementing the length this.length-- + return removedNode.data + } + + // make the linkedList Empty + clean () { + this.headNode = null + this.length = 0 } // Method to get the LinkedList get () { const list = [] - let currentNode = this.headNode + let { currentNode } = this.initiateNodeAndIndex() while (currentNode) { list.push(currentNode.data) currentNode = currentNode.next @@ -214,7 +214,7 @@ class LinkedList { // Method to iterate over the LinkedList iterator () { - let currentNode = this.headNode + let { currentNode } = this.initiateNodeAndIndex() if (currentNode === null) return -1 const iterate = function * () { diff --git a/Data-Structures/Linked-List/test/SinglyLinkedList.test.js b/Data-Structures/Linked-List/test/SinglyLinkedList.test.js index 1b44b3e5a..4bfde62c8 100644 --- a/Data-Structures/Linked-List/test/SinglyLinkedList.test.js +++ b/Data-Structures/Linked-List/test/SinglyLinkedList.test.js @@ -5,38 +5,38 @@ describe('SinglyLinkedList', () => { const list = new LinkedList() expect(list.get()).toEqual([]) - list.addLast(1) + expect(list.addLast(1)).toEqual(1) expect(list.get()).toEqual([1]) - list.addLast(2) - expect(list.get()).toEqual([1, 2]) + expect(list.addLast(5)).toEqual(2) + expect(list.get()).toEqual([1, 5]) }) it('Check addFirst', () => { const list = new LinkedList() expect(list.get()).toEqual([]) - list.addFirst(1) + expect(list.addFirst(1)).toEqual(1) expect(list.get()).toEqual([1]) - list.addFirst(2) - expect(list.get()).toEqual([2, 1]) + expect(list.addFirst(5)).toEqual(2) + expect(list.get()).toEqual([5, 1]) }) it('Check addAt', () => { const list = new LinkedList() expect(list.get()).toEqual([]) - list.addAt(0, 10) + expect(list.addAt(0, 10)).toEqual(1) expect(list.get()).toEqual([10]) - list.addAt(1, 20) + expect(list.addAt(1, 20)).toEqual(2) expect(list.get()).toEqual([10, 20]) - list.addAt(1, 30) + expect(list.addAt(1, 30)).toEqual(3) expect(list.get()).toEqual([10, 30, 20]) - list.addAt(3, 40) + expect(list.addAt(3, 40)).toEqual(4) expect(list.get()).toEqual([10, 30, 20, 40]) }) @@ -46,10 +46,10 @@ describe('SinglyLinkedList', () => { list.addLast(2) expect(list.get()).toEqual([1, 2]) - list.removeLast() + expect(list.removeLast()).toEqual(2) expect(list.get()).toEqual([1]) - list.removeLast() + expect(list.removeLast()).toEqual(1) expect(list.get()).toEqual([]) }) @@ -59,10 +59,10 @@ describe('SinglyLinkedList', () => { list.addLast(2) expect(list.get()).toEqual([1, 2]) - list.removeFirst() + expect(list.removeFirst()).toEqual(1) expect(list.get()).toEqual([2]) - list.removeFirst() + expect(list.removeFirst()).toEqual(2) expect(list.get()).toEqual([]) }) @@ -75,13 +75,13 @@ describe('SinglyLinkedList', () => { list.addLast(50) expect(list.get()).toEqual([10, 20, 30, 40, 50]) - list.removeAt(0) + expect(list.removeAt(0)).toEqual(10) expect(list.get()).toEqual([20, 30, 40, 50]) - list.removeAt(3) + expect(list.removeAt(3)).toEqual(50) expect(list.get()).toEqual([20, 30, 40]) - list.removeAt(1) + expect(list.removeAt(1)).toEqual(30) expect(list.get()).toEqual([20, 40]) }) @@ -92,11 +92,11 @@ describe('SinglyLinkedList', () => { list.addLast(30) expect(list.get()).toEqual([10, 20, 30]) - list.remove(20) - expect(list.get()).toEqual([10, 30]) + expect(list.remove(10)).toEqual(10) + expect(list.get()).toEqual([20, 30]) - list.remove(30) - expect(list.get()).toEqual([10]) + expect(list.remove(100)).toEqual(null) + expect(list.get()).toEqual([20, 30]) }) it('Check indexOf', () => { @@ -188,4 +188,15 @@ describe('SinglyLinkedList', () => { count++ } }) + it('Cleans the linkedList', () => { + const list = new LinkedList() + list.addLast(10) + list.addLast(20) + list.addLast(30) + list.addLast(40) + list.addLast(50) + expect(list.size()).toEqual(5) + list.clean() + expect(list.isEmpty()).toBe(true) + }) })