diff --git a/Data-Structures/Linked-List/SingleCircularLinkedList.js.js b/Data-Structures/Linked-List/SingleCircularLinkedList.js.js deleted file mode 100644 index 2ba354191..000000000 --- a/Data-Structures/Linked-List/SingleCircularLinkedList.js.js +++ /dev/null @@ -1,88 +0,0 @@ -class Node { - constructor (data, next = null) { - this.data = data - this.next = next - } -} - -class SinglyCircularLinkedList { - constructor () { - this.head = null - this.size = 0 - } - - insert (data) { - const node = new Node(data) - - if (!this.head) { - node.next = node - this.head = node - this.size++ - } else { - node.next = this.head - - let current = this.head - - while (current.next.data !== this.head.data) { - current = current.next - } - - current.next = node - this.size++ - } - } - - insertAt (index, data) { - const node = new Node(data) - - if (index < 0 || index > this.size) return - - if (index === 0) { - this.head = node - this.size = 1 - return - } - - let previous - let count = 0 - let current = this.head - - while (count < index) { - previous = current - current = current.next - count++ - } - - node.next = current - previous.next = node - this.size++ - } - - remove () { - if (!this.head) return - - let prev - let current = this.head - - while (current.next !== this.head) { - prev = current - current = current.next - } - - prev.next = this.head - this.size-- - } - - printData (output = value => console.log(value)) { - let count = 0 - let current = this.head - - while (current !== null && count < this.size) { - output(current.data) - current = current.next - count++ - } - } -} - -export { SinglyCircularLinkedList } diff --git a/Data-Structures/Linked-List/SinglyCircularLinkedList.js b/Data-Structures/Linked-List/SinglyCircularLinkedList.js new file mode 100644 index 000000000..e1a8085f8 --- /dev/null +++ b/Data-Structures/Linked-List/SinglyCircularLinkedList.js @@ -0,0 +1,157 @@ +// Methods - size, head, isEmpty, getElementAt, addAtFirst, add, clean, insertAt, remove, removeData, printData, get, clear +import { Node } from './SinglyLinkedList.js' + +class SinglyCircularLinkedList { + constructor () { + this.headNode = null + this.length = 0 + } + + // Get size of the linkedList + size = () => this.length + // Get the headNode data + head = () => this.headNode?.data || null + // Check if the linkedList is empty + isEmpty = () => this.length === 0 + + // initiate the node and index + initiateNodeAndIndex () { + return { currentNode: this.headNode, currentIndex: 0 } + } + + // get the data specific to an index + getElementAt (index) { + if (this.length !== 0 && index >= 0 && index <= this.length) { + let { currentNode } = this.initiateNodeAndIndex() + for (let i = 0; i < index && currentNode !== null; i++) { + currentNode = currentNode.next + } + return currentNode + } + return undefined + } + + // Add the element in the first position + addAtFirst (data) { + const node = new Node(data) + node.next = this.headNode + this.headNode = node + this.length++ + return this.length + } + + // Add any data to the end of the linkedList + add (data) { + if (!this.headNode) { return this.addAtFirst(data) } + const node = new Node(data) + // Getting the last node + const currentNode = this.getElementAt(this.length - 1) + currentNode.next = node + node.next = this.headNode + this.length++ + return this.length + } + + // insert data at a specific position + insertAt (index, data) { + if (index === 0) return this.addAtFirst(data) + if (index === this.length) return this.add(data) + if (index < 0 || index > this.length) throw new RangeError(`Index is out of range max ${this.length}`) + const node = new Node(data) + const previousNode = this.getElementAt(index - 1) + node.next = previousNode.next + previousNode.next = node + this.length++ + return this.length + } + + // find the first index of the data + indexOf (data) { + let { currentNode } = this.initiateNodeAndIndex() + // initializing currentIndex as -1 + let currentIndex = -1 + while (currentNode) { + if (currentNode.data === data) { + return currentIndex + 1 + } + currentIndex++ + currentNode = currentNode.next + } + return -1 + } + + // remove the data from the end of the list + remove () { + if (this.isEmpty()) return null + const secondLastNode = this.getElementAt(this.length - 2) + const removedNode = secondLastNode.next + secondLastNode.next = this.headNode + this.length-- + return removedNode.data || null + } + + // remove the data from the first of the list + removeFirst () { + if (this.isEmpty()) return null + const removedNode = this.headNode + if (this.length === 1) { + this.clear() + return removedNode.data + } + const lastNode = this.getElementAt(this.length - 1) + this.headNode = this.headNode.next + lastNode.next = this.headNode + this.length-- + return removedNode.data || null + } + + // remove the data from the index + removeAt (index) { + if (this.isEmpty()) return null + if (index === 0) return this.removeFirst() + if (index === this.length) return this.remove() + if (index < 0 && index > this.length) return null + const previousNode = this.getElementAt(index - 1) + const currentNode = previousNode.next + previousNode.next = currentNode.next + this.length-- + return currentNode.data || null + } + + // remove if the data is present + removeData (data) { + if (this.isEmpty()) return null + const index = this.indexOf(data) + return this.removeAt(index) + } + + // logs the data + printData (output = value => console.log(value)) { + let { currentIndex, currentNode } = this.initiateNodeAndIndex() + + while (currentNode !== null && currentIndex < this.length) { + output(currentNode.data) + currentNode = currentNode.next + currentIndex++ + } + } + + // get the data from the linkedList + get () { + let { currentIndex, currentNode } = this.initiateNodeAndIndex() + const list = [] + while (currentNode !== null && currentIndex < this.length) { + list.push(currentNode.data) + currentNode = currentNode.next + currentIndex++ + } + return list + } + + clear () { + this.headNode = null + this.length = 0 + } +} + +export { SinglyCircularLinkedList } diff --git a/Data-Structures/Linked-List/test/SinglyCircularLinkedList.test.js b/Data-Structures/Linked-List/test/SinglyCircularLinkedList.test.js new file mode 100644 index 000000000..8f5087c53 --- /dev/null +++ b/Data-Structures/Linked-List/test/SinglyCircularLinkedList.test.js @@ -0,0 +1,147 @@ +import { SinglyCircularLinkedList } from '../SinglyCircularLinkedList' + +describe('SinglyCircularLinkedList', () => { + let list + beforeEach(() => { + list = new SinglyCircularLinkedList() + }) + it('Check get', () => { + expect(list.get()).toEqual([]) + expect(list.add(1)).toEqual(1) + expect(list.get()).toEqual([1]) + expect(list.add(5)).toEqual(2) + expect(list.get()).toEqual([1, 5]) + }) + + it('Check size', () => { + expect(list.size()).toEqual(0) + expect(list.add(1)).toEqual(1) + expect(list.add(1)).toEqual(2) + expect(list.size()).toEqual(2) + }) + + it('Check head', () => { + expect(list.head()).toEqual(null) + expect(list.add(1)).toEqual(1) + expect(list.head()).toEqual(1) + expect(list.add(1)).toEqual(2) + expect(list.head()).toEqual(1) + expect(list.addAtFirst(100)).toEqual(3) + expect(list.head()).toEqual(100) + expect(list.insertAt(0, 500)).toEqual(4) + expect(list.head()).toEqual(500) + list.clear() + expect(list.head()).toEqual(null) + }) + + it('Check isEmpty', () => { + expect(list.isEmpty()).toEqual(true) + expect(list.add(1)).toEqual(1) + expect(list.add(1)).toEqual(2) + expect(list.isEmpty()).toEqual(false) + }) + + it('Check getElementAt', () => { + list.add(100) + list.add(200) + list.add(300) + list.add(500) + list.add(900) + + expect(list.getElementAt(1).data).toEqual(200) + expect(list.getElementAt(3).data).toEqual(500) + }) + + it('Check addAtFirst', () => { + list.add(1) + list.add(5) + list.add(7) + list.add(9) + list.add(0) + expect(list.get()).toEqual([1, 5, 7, 9, 0]) + list.addAtFirst(100) + expect(list.get()).toEqual([100, 1, 5, 7, 9, 0]) + }) + + it('Check add', () => { + list.add(1) + list.add(5) + list.add(7) + list.add(9) + list.add(0) + expect(list.get()).toEqual([1, 5, 7, 9, 0]) + list.add(100) + expect(list.get()).toEqual([1, 5, 7, 9, 0, 100]) + }) + + it('Check insertAt', () => { + expect(list.insertAt(0, 100)).toEqual(1) + expect(list.get()).toEqual([100]) + expect(list.insertAt(0, 200)).toEqual(2) + expect(list.get()).toEqual([200, 100]) + expect(list.insertAt(2, 300)).toEqual(3) + expect(list.get()).toEqual([200, 100, 300]) + }) + + it('Checks indexOf', () => { + expect(list.indexOf(200)).toEqual(-1) + list.add(100) + list.add(200) + list.add(300) + list.add(500) + list.add(900) + expect(list.indexOf(200)).toEqual(1) + }) + + it('Check remove', () => { + expect(list.remove()).toEqual(null) + list.add(100) + list.add(200) + list.add(300) + list.add(500) + list.add(900) + expect(list.get()).toEqual([100, 200, 300, 500, 900]) + const removedData = list.remove() + expect(removedData).toEqual(900) + expect(list.get()).toEqual([100, 200, 300, 500]) + }) + + it('Check removeFirst', () => { + expect(list.removeFirst()).toEqual(null) + list.add(100) + list.add(200) + list.add(300) + list.add(500) + list.add(900) + expect(list.get()).toEqual([100, 200, 300, 500, 900]) + const removedData = list.removeFirst() + expect(removedData).toEqual(100) + expect(list.get()).toEqual([200, 300, 500, 900]) + }) + + it('Check removeAt', () => { + expect(list.removeAt(1)).toEqual(null) + list.add(100) + list.add(200) + list.add(300) + list.add(500) + list.add(900) + expect(list.get()).toEqual([100, 200, 300, 500, 900]) + const removedData = list.removeAt(2) + expect(removedData).toEqual(300) + expect(list.get()).toEqual([100, 200, 500, 900]) + }) + + it('Check removeData', () => { + expect(list.removeData(100)).toEqual(null) + list.add(100) + list.add(200) + list.add(300) + list.add(500) + list.add(900) + expect(list.get()).toEqual([100, 200, 300, 500, 900]) + const removedData = list.removeData(200) + expect(removedData).toEqual(200) + expect(list.get()).toEqual([100, 300, 500, 900]) + }) +})