merge: Improvement on singly circular linkedList (#981)

* Auto-update DIRECTORY.md

* Update and rename SingleCircularLinkedList.js.js to SinglyCircularLinkedList.js

* Test Case creation for SinglyCircularLinkedList

* Update SinglyCircularLinkedList.js

* Update SinglyCircularLinkedList.test.js

* Update SinglyCircularLinkedList.js

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
Rahul Raj
2022-04-10 15:36:48 +05:30
committed by GitHub
parent dfe200a957
commit 74857b7a9e
3 changed files with 304 additions and 88 deletions

View File

@ -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 }

View File

@ -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 }

View File

@ -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])
})
})