-
Notifications
You must be signed in to change notification settings - Fork 0
/
SinglyCircularLinkedList.js
157 lines (140 loc) · 4.28 KB
/
SinglyCircularLinkedList.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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 }