Skip to content

Commit 74857b7

Browse files
rahulrajrdgithub-actions
andauthored
merge: Improvement on singly circular linkedList (TheAlgorithms#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>
1 parent dfe200a commit 74857b7

File tree

3 files changed

+304
-88
lines changed

3 files changed

+304
-88
lines changed

Data-Structures/Linked-List/SingleCircularLinkedList.js.js

Lines changed: 0 additions & 88 deletions
This file was deleted.
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Methods - size, head, isEmpty, getElementAt, addAtFirst, add, clean, insertAt, remove, removeData, printData, get, clear
2+
import { Node } from './SinglyLinkedList.js'
3+
4+
class SinglyCircularLinkedList {
5+
constructor () {
6+
this.headNode = null
7+
this.length = 0
8+
}
9+
10+
// Get size of the linkedList
11+
size = () => this.length
12+
// Get the headNode data
13+
head = () => this.headNode?.data || null
14+
// Check if the linkedList is empty
15+
isEmpty = () => this.length === 0
16+
17+
// initiate the node and index
18+
initiateNodeAndIndex () {
19+
return { currentNode: this.headNode, currentIndex: 0 }
20+
}
21+
22+
// get the data specific to an index
23+
getElementAt (index) {
24+
if (this.length !== 0 && index >= 0 && index <= this.length) {
25+
let { currentNode } = this.initiateNodeAndIndex()
26+
for (let i = 0; i < index && currentNode !== null; i++) {
27+
currentNode = currentNode.next
28+
}
29+
return currentNode
30+
}
31+
return undefined
32+
}
33+
34+
// Add the element in the first position
35+
addAtFirst (data) {
36+
const node = new Node(data)
37+
node.next = this.headNode
38+
this.headNode = node
39+
this.length++
40+
return this.length
41+
}
42+
43+
// Add any data to the end of the linkedList
44+
add (data) {
45+
if (!this.headNode) { return this.addAtFirst(data) }
46+
const node = new Node(data)
47+
// Getting the last node
48+
const currentNode = this.getElementAt(this.length - 1)
49+
currentNode.next = node
50+
node.next = this.headNode
51+
this.length++
52+
return this.length
53+
}
54+
55+
// insert data at a specific position
56+
insertAt (index, data) {
57+
if (index === 0) return this.addAtFirst(data)
58+
if (index === this.length) return this.add(data)
59+
if (index < 0 || index > this.length) throw new RangeError(`Index is out of range max ${this.length}`)
60+
const node = new Node(data)
61+
const previousNode = this.getElementAt(index - 1)
62+
node.next = previousNode.next
63+
previousNode.next = node
64+
this.length++
65+
return this.length
66+
}
67+
68+
// find the first index of the data
69+
indexOf (data) {
70+
let { currentNode } = this.initiateNodeAndIndex()
71+
// initializing currentIndex as -1
72+
let currentIndex = -1
73+
while (currentNode) {
74+
if (currentNode.data === data) {
75+
return currentIndex + 1
76+
}
77+
currentIndex++
78+
currentNode = currentNode.next
79+
}
80+
return -1
81+
}
82+
83+
// remove the data from the end of the list
84+
remove () {
85+
if (this.isEmpty()) return null
86+
const secondLastNode = this.getElementAt(this.length - 2)
87+
const removedNode = secondLastNode.next
88+
secondLastNode.next = this.headNode
89+
this.length--
90+
return removedNode.data || null
91+
}
92+
93+
// remove the data from the first of the list
94+
removeFirst () {
95+
if (this.isEmpty()) return null
96+
const removedNode = this.headNode
97+
if (this.length === 1) {
98+
this.clear()
99+
return removedNode.data
100+
}
101+
const lastNode = this.getElementAt(this.length - 1)
102+
this.headNode = this.headNode.next
103+
lastNode.next = this.headNode
104+
this.length--
105+
return removedNode.data || null
106+
}
107+
108+
// remove the data from the index
109+
removeAt (index) {
110+
if (this.isEmpty()) return null
111+
if (index === 0) return this.removeFirst()
112+
if (index === this.length) return this.remove()
113+
if (index < 0 && index > this.length) return null
114+
const previousNode = this.getElementAt(index - 1)
115+
const currentNode = previousNode.next
116+
previousNode.next = currentNode.next
117+
this.length--
118+
return currentNode.data || null
119+
}
120+
121+
// remove if the data is present
122+
removeData (data) {
123+
if (this.isEmpty()) return null
124+
const index = this.indexOf(data)
125+
return this.removeAt(index)
126+
}
127+
128+
// logs the data
129+
printData (output = value => console.log(value)) {
130+
let { currentIndex, currentNode } = this.initiateNodeAndIndex()
131+
132+
while (currentNode !== null && currentIndex < this.length) {
133+
output(currentNode.data)
134+
currentNode = currentNode.next
135+
currentIndex++
136+
}
137+
}
138+
139+
// get the data from the linkedList
140+
get () {
141+
let { currentIndex, currentNode } = this.initiateNodeAndIndex()
142+
const list = []
143+
while (currentNode !== null && currentIndex < this.length) {
144+
list.push(currentNode.data)
145+
currentNode = currentNode.next
146+
currentIndex++
147+
}
148+
return list
149+
}
150+
151+
clear () {
152+
this.headNode = null
153+
this.length = 0
154+
}
155+
}
156+
157+
export { SinglyCircularLinkedList }
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import { SinglyCircularLinkedList } from '../SinglyCircularLinkedList'
2+
3+
describe('SinglyCircularLinkedList', () => {
4+
let list
5+
beforeEach(() => {
6+
list = new SinglyCircularLinkedList()
7+
})
8+
it('Check get', () => {
9+
expect(list.get()).toEqual([])
10+
expect(list.add(1)).toEqual(1)
11+
expect(list.get()).toEqual([1])
12+
expect(list.add(5)).toEqual(2)
13+
expect(list.get()).toEqual([1, 5])
14+
})
15+
16+
it('Check size', () => {
17+
expect(list.size()).toEqual(0)
18+
expect(list.add(1)).toEqual(1)
19+
expect(list.add(1)).toEqual(2)
20+
expect(list.size()).toEqual(2)
21+
})
22+
23+
it('Check head', () => {
24+
expect(list.head()).toEqual(null)
25+
expect(list.add(1)).toEqual(1)
26+
expect(list.head()).toEqual(1)
27+
expect(list.add(1)).toEqual(2)
28+
expect(list.head()).toEqual(1)
29+
expect(list.addAtFirst(100)).toEqual(3)
30+
expect(list.head()).toEqual(100)
31+
expect(list.insertAt(0, 500)).toEqual(4)
32+
expect(list.head()).toEqual(500)
33+
list.clear()
34+
expect(list.head()).toEqual(null)
35+
})
36+
37+
it('Check isEmpty', () => {
38+
expect(list.isEmpty()).toEqual(true)
39+
expect(list.add(1)).toEqual(1)
40+
expect(list.add(1)).toEqual(2)
41+
expect(list.isEmpty()).toEqual(false)
42+
})
43+
44+
it('Check getElementAt', () => {
45+
list.add(100)
46+
list.add(200)
47+
list.add(300)
48+
list.add(500)
49+
list.add(900)
50+
51+
expect(list.getElementAt(1).data).toEqual(200)
52+
expect(list.getElementAt(3).data).toEqual(500)
53+
})
54+
55+
it('Check addAtFirst', () => {
56+
list.add(1)
57+
list.add(5)
58+
list.add(7)
59+
list.add(9)
60+
list.add(0)
61+
expect(list.get()).toEqual([1, 5, 7, 9, 0])
62+
list.addAtFirst(100)
63+
expect(list.get()).toEqual([100, 1, 5, 7, 9, 0])
64+
})
65+
66+
it('Check add', () => {
67+
list.add(1)
68+
list.add(5)
69+
list.add(7)
70+
list.add(9)
71+
list.add(0)
72+
expect(list.get()).toEqual([1, 5, 7, 9, 0])
73+
list.add(100)
74+
expect(list.get()).toEqual([1, 5, 7, 9, 0, 100])
75+
})
76+
77+
it('Check insertAt', () => {
78+
expect(list.insertAt(0, 100)).toEqual(1)
79+
expect(list.get()).toEqual([100])
80+
expect(list.insertAt(0, 200)).toEqual(2)
81+
expect(list.get()).toEqual([200, 100])
82+
expect(list.insertAt(2, 300)).toEqual(3)
83+
expect(list.get()).toEqual([200, 100, 300])
84+
})
85+
86+
it('Checks indexOf', () => {
87+
expect(list.indexOf(200)).toEqual(-1)
88+
list.add(100)
89+
list.add(200)
90+
list.add(300)
91+
list.add(500)
92+
list.add(900)
93+
expect(list.indexOf(200)).toEqual(1)
94+
})
95+
96+
it('Check remove', () => {
97+
expect(list.remove()).toEqual(null)
98+
list.add(100)
99+
list.add(200)
100+
list.add(300)
101+
list.add(500)
102+
list.add(900)
103+
expect(list.get()).toEqual([100, 200, 300, 500, 900])
104+
const removedData = list.remove()
105+
expect(removedData).toEqual(900)
106+
expect(list.get()).toEqual([100, 200, 300, 500])
107+
})
108+
109+
it('Check removeFirst', () => {
110+
expect(list.removeFirst()).toEqual(null)
111+
list.add(100)
112+
list.add(200)
113+
list.add(300)
114+
list.add(500)
115+
list.add(900)
116+
expect(list.get()).toEqual([100, 200, 300, 500, 900])
117+
const removedData = list.removeFirst()
118+
expect(removedData).toEqual(100)
119+
expect(list.get()).toEqual([200, 300, 500, 900])
120+
})
121+
122+
it('Check removeAt', () => {
123+
expect(list.removeAt(1)).toEqual(null)
124+
list.add(100)
125+
list.add(200)
126+
list.add(300)
127+
list.add(500)
128+
list.add(900)
129+
expect(list.get()).toEqual([100, 200, 300, 500, 900])
130+
const removedData = list.removeAt(2)
131+
expect(removedData).toEqual(300)
132+
expect(list.get()).toEqual([100, 200, 500, 900])
133+
})
134+
135+
it('Check removeData', () => {
136+
expect(list.removeData(100)).toEqual(null)
137+
list.add(100)
138+
list.add(200)
139+
list.add(300)
140+
list.add(500)
141+
list.add(900)
142+
expect(list.get()).toEqual([100, 200, 300, 500, 900])
143+
const removedData = list.removeData(200)
144+
expect(removedData).toEqual(200)
145+
expect(list.get()).toEqual([100, 300, 500, 900])
146+
})
147+
})

0 commit comments

Comments
 (0)