mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-06 01:18:23 +08:00
merge: Add test case and enacements (#858)
This commit is contained in:
@ -6,45 +6,40 @@
|
|||||||
* a singly linked list.
|
* a singly linked list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Functions - add, remove, indexOf, elementAt, addAt, removeAt, view
|
// Methods - size, head, addLast, addFirst, addAt, removeFirst, removeLast, remove, removeAt, indexOf, isEmpty, elementAt, get
|
||||||
|
|
||||||
// class LinkedList and constructor
|
class Node {
|
||||||
// Creates a LinkedList
|
constructor (data) {
|
||||||
const LinkedList = (function () {
|
this.data = data
|
||||||
function LinkedList () {
|
this.next = null
|
||||||
// Length of linklist and head is null at start
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkedList {
|
||||||
|
constructor () {
|
||||||
|
this.headNode = null
|
||||||
this.length = 0
|
this.length = 0
|
||||||
this.head = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class node (constructor)
|
|
||||||
// Creating Node with element's value
|
|
||||||
const Node = (function () {
|
|
||||||
function Node (element) {
|
|
||||||
this.element = element
|
|
||||||
this.next = null
|
|
||||||
}
|
|
||||||
return Node
|
|
||||||
}())
|
|
||||||
|
|
||||||
// Returns length
|
// Returns length
|
||||||
LinkedList.prototype.size = function () {
|
size () {
|
||||||
return this.length
|
return this.length
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the head
|
// Returns the head
|
||||||
LinkedList.prototype.head = function () {
|
head () {
|
||||||
return this.head
|
return this.headNode ? this.headNode.data : null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a node and adds it to linklist
|
// add a node at last it to linklist
|
||||||
LinkedList.prototype.add = function (element) {
|
addLast (element) {
|
||||||
const node = new Node(element)
|
const node = new Node(element)
|
||||||
|
|
||||||
// Check if its the first element
|
// Check if its the first element
|
||||||
if (this.head === null) {
|
if (this.headNode === null) {
|
||||||
this.head = node
|
this.headNode = node
|
||||||
} else {
|
} else {
|
||||||
let currentNode = this.head
|
let currentNode = this.headNode
|
||||||
|
|
||||||
// Loop till there is a node present in the list
|
// Loop till there is a node present in the list
|
||||||
while (currentNode.next) {
|
while (currentNode.next) {
|
||||||
@ -54,144 +49,168 @@ const LinkedList = (function () {
|
|||||||
// Adding node at the end of the list
|
// Adding node at the end of the list
|
||||||
currentNode.next = node
|
currentNode.next = node
|
||||||
}
|
}
|
||||||
// Increment the length
|
|
||||||
this.length++
|
this.length++ // Increment the length
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes the node with the value as param
|
// add a node at first it to linklist
|
||||||
LinkedList.prototype.remove = function (element) {
|
addFirst (element) {
|
||||||
let currentNode = this.head
|
const node = new Node(element)
|
||||||
let previousNode
|
node.next = this.headNode
|
||||||
|
this.headNode = node
|
||||||
|
this.length++ // Increment the length
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the head node is the element to remove
|
// remove the first from the linklist
|
||||||
if (currentNode.element === element) {
|
removeFirst () {
|
||||||
this.head = currentNode.next
|
if (this.length > 0) {
|
||||||
} else {
|
this.headNode = this.headNode.next
|
||||||
// Check which node is the node to remove
|
this.length--
|
||||||
while (currentNode.element !== element) {
|
}
|
||||||
previousNode = currentNode
|
}
|
||||||
|
|
||||||
|
// 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 = currentNode.next
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removing the currentNode
|
currentNode.next = null
|
||||||
previousNode.next = currentNode.next
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrementing the length
|
this.length-- // Decrementing the length
|
||||||
this.length--
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return if the list is empty
|
// Return if the list is empty
|
||||||
LinkedList.prototype.isEmpty = function () {
|
isEmpty () {
|
||||||
return this.length === 0
|
return this.length === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the index of the element passed as param otherwise -1
|
// Returns the index of the element passed as param otherwise -1
|
||||||
LinkedList.prototype.indexOf = function (element) {
|
indexOf (element) {
|
||||||
let currentNode = this.head
|
let currentNode = this.headNode
|
||||||
let index = -1
|
let index = 0
|
||||||
|
|
||||||
while (currentNode) {
|
while (currentNode) {
|
||||||
index++
|
|
||||||
|
|
||||||
// Checking if the node is the element we are searching for
|
// Checking if the node is the element we are searching for
|
||||||
if (currentNode.element === element) {
|
if (currentNode.data === element) {
|
||||||
return index + 1
|
return index
|
||||||
}
|
}
|
||||||
currentNode = currentNode.next
|
currentNode = currentNode.next
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the element at an index
|
// Returns the element at an index
|
||||||
LinkedList.prototype.elementAt = function (index) {
|
elementAt (index) {
|
||||||
let currentNode = this.head
|
if (index >= this.length || index < 0) {
|
||||||
|
throw new RangeError('Out of Range index')
|
||||||
|
}
|
||||||
|
let currentNode = this.headNode
|
||||||
let count = 0
|
let count = 0
|
||||||
while (count < index) {
|
while (count < index) {
|
||||||
count++
|
count++
|
||||||
currentNode = currentNode.next
|
currentNode = currentNode.next
|
||||||
}
|
}
|
||||||
return currentNode.element
|
return currentNode.data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds the element at specified index
|
// Adds the element at specified index
|
||||||
LinkedList.prototype.addAt = function (index, element) {
|
addAt (index, element) {
|
||||||
index--
|
|
||||||
const node = new Node(element)
|
const node = new Node(element)
|
||||||
|
|
||||||
let currentNode = this.head
|
|
||||||
let previousNode
|
|
||||||
let currentIndex = 0
|
|
||||||
|
|
||||||
// Check if index is out of bounds of list
|
// Check if index is out of bounds of list
|
||||||
if (index > this.length) {
|
if (index > this.length || index < 0) {
|
||||||
return false
|
throw new RangeError('Out of Range index')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentNode = this.headNode
|
||||||
|
let currentIndex = 0
|
||||||
// Check if index is the start of list
|
// Check if index is the start of list
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
node.next = currentNode
|
node.next = currentNode
|
||||||
this.head = node
|
this.headNode = node
|
||||||
} else {
|
} else {
|
||||||
while (currentIndex < index) {
|
while (currentIndex !== index - 1) {
|
||||||
currentIndex++
|
currentIndex++
|
||||||
previousNode = currentNode
|
|
||||||
currentNode = currentNode.next
|
currentNode = currentNode.next
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adding the node at specified index
|
// Adding the node at specified index
|
||||||
node.next = currentNode
|
const temp = currentNode.next
|
||||||
previousNode.next = node
|
currentNode.next = node
|
||||||
|
node.next = temp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incrementing the length
|
// Incrementing the length
|
||||||
this.length++
|
this.length++
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes the node at specified index
|
// Removes the node at specified index
|
||||||
LinkedList.prototype.removeAt = function (index) {
|
removeAt (index) {
|
||||||
index--
|
let currentNode = this.headNode
|
||||||
let currentNode = this.head
|
|
||||||
let previousNode
|
|
||||||
let currentIndex = 0
|
let currentIndex = 0
|
||||||
|
|
||||||
// Check if index is present in list
|
// Check if index is present in list
|
||||||
if (index < 0 || index >= this.length) {
|
if (index < 0 || index >= this.length) {
|
||||||
return null
|
throw new RangeError('Out of Range index')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if element is the first element
|
// Check if element is the first element
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
this.head = currentNode.next
|
this.headNode = currentNode.next
|
||||||
} else {
|
} else {
|
||||||
while (currentIndex < index) {
|
while (currentIndex !== index - 1) {
|
||||||
currentIndex++
|
currentIndex++
|
||||||
previousNode = currentNode
|
|
||||||
currentNode = currentNode.next
|
currentNode = currentNode.next
|
||||||
}
|
}
|
||||||
previousNode.next = currentNode.next
|
currentNode.next = currentNode.next.next
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrementing the length
|
// Decrementing the length
|
||||||
this.length--
|
this.length--
|
||||||
return currentNode.element
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to view the LinkedList
|
// Method to get the LinkedList
|
||||||
LinkedList.prototype.view = function (output = value => console.log(value)) {
|
get () {
|
||||||
let currentNode = this.head
|
const list = []
|
||||||
let count = 0
|
let currentNode = this.headNode
|
||||||
while (count < this.length) {
|
while (currentNode) {
|
||||||
count++
|
list.push(currentNode.data)
|
||||||
output(currentNode.element)
|
|
||||||
currentNode = currentNode.next
|
currentNode = currentNode.next
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// returns the constructor
|
return list
|
||||||
return LinkedList
|
}
|
||||||
}())
|
}
|
||||||
|
|
||||||
export { LinkedList }
|
export { LinkedList }
|
||||||
|
166
Data-Structures/Linked-List/test/SinglyLinkList.test.js
Normal file
166
Data-Structures/Linked-List/test/SinglyLinkList.test.js
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
import { LinkedList } from '../SinglyLinkList'
|
||||||
|
|
||||||
|
describe('SinglyLinkList', () => {
|
||||||
|
it('Check addLast', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
expect(list.get()).toEqual([])
|
||||||
|
|
||||||
|
list.addLast(1)
|
||||||
|
expect(list.get()).toEqual([1])
|
||||||
|
|
||||||
|
list.addLast(2)
|
||||||
|
expect(list.get()).toEqual([1, 2])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check addFirst', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
expect(list.get()).toEqual([])
|
||||||
|
|
||||||
|
list.addFirst(1)
|
||||||
|
expect(list.get()).toEqual([1])
|
||||||
|
|
||||||
|
list.addFirst(2)
|
||||||
|
expect(list.get()).toEqual([2, 1])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check addAt', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
expect(list.get()).toEqual([])
|
||||||
|
|
||||||
|
list.addAt(0, 10)
|
||||||
|
expect(list.get()).toEqual([10])
|
||||||
|
|
||||||
|
list.addAt(1, 20)
|
||||||
|
expect(list.get()).toEqual([10, 20])
|
||||||
|
|
||||||
|
list.addAt(1, 30)
|
||||||
|
expect(list.get()).toEqual([10, 30, 20])
|
||||||
|
|
||||||
|
list.addAt(3, 40)
|
||||||
|
expect(list.get()).toEqual([10, 30, 20, 40])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check removeLast', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
list.addLast(1)
|
||||||
|
list.addLast(2)
|
||||||
|
expect(list.get()).toEqual([1, 2])
|
||||||
|
|
||||||
|
list.removeLast()
|
||||||
|
expect(list.get()).toEqual([1])
|
||||||
|
|
||||||
|
list.removeLast()
|
||||||
|
expect(list.get()).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check removeFirst', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
list.addLast(1)
|
||||||
|
list.addLast(2)
|
||||||
|
expect(list.get()).toEqual([1, 2])
|
||||||
|
|
||||||
|
list.removeFirst()
|
||||||
|
expect(list.get()).toEqual([2])
|
||||||
|
|
||||||
|
list.removeFirst()
|
||||||
|
expect(list.get()).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check removeAt', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
list.addLast(10)
|
||||||
|
list.addLast(20)
|
||||||
|
list.addLast(30)
|
||||||
|
list.addLast(40)
|
||||||
|
list.addLast(50)
|
||||||
|
expect(list.get()).toEqual([10, 20, 30, 40, 50])
|
||||||
|
|
||||||
|
list.removeAt(0)
|
||||||
|
expect(list.get()).toEqual([20, 30, 40, 50])
|
||||||
|
|
||||||
|
list.removeAt(3)
|
||||||
|
expect(list.get()).toEqual([20, 30, 40])
|
||||||
|
|
||||||
|
list.removeAt(1)
|
||||||
|
expect(list.get()).toEqual([20, 40])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check remove', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
list.addLast(10)
|
||||||
|
list.addLast(20)
|
||||||
|
list.addLast(30)
|
||||||
|
expect(list.get()).toEqual([10, 20, 30])
|
||||||
|
|
||||||
|
list.remove(20)
|
||||||
|
expect(list.get()).toEqual([10, 30])
|
||||||
|
|
||||||
|
list.remove(30)
|
||||||
|
expect(list.get()).toEqual([10])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check indexOf', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
list.addLast(10)
|
||||||
|
list.addLast(20)
|
||||||
|
list.addLast(30)
|
||||||
|
list.addLast(40)
|
||||||
|
list.addLast(50)
|
||||||
|
expect(list.indexOf(10)).toBe(0)
|
||||||
|
expect(list.indexOf(30)).toBe(2)
|
||||||
|
expect(list.indexOf(50)).toBe(4)
|
||||||
|
expect(list.indexOf(70)).toBe(-1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check elementAt', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
list.addLast(10)
|
||||||
|
list.addLast(20)
|
||||||
|
list.addLast(30)
|
||||||
|
list.addLast(40)
|
||||||
|
list.addLast(50)
|
||||||
|
expect(list.elementAt(0)).toBe(10)
|
||||||
|
expect(list.elementAt(1)).toBe(20)
|
||||||
|
expect(list.elementAt(3)).toBe(40)
|
||||||
|
expect(list.elementAt(4)).toBe(50)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check isEmpty', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
expect(list.isEmpty()).toBe(true)
|
||||||
|
list.addLast(10)
|
||||||
|
list.addLast(20)
|
||||||
|
list.addLast(30)
|
||||||
|
list.addLast(40)
|
||||||
|
list.addLast(50)
|
||||||
|
expect(list.isEmpty()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check head', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
expect(list.head()).toBe(null)
|
||||||
|
|
||||||
|
list.addLast(10)
|
||||||
|
expect(list.head()).toBe(10)
|
||||||
|
|
||||||
|
list.addLast(20)
|
||||||
|
expect(list.head()).toBe(10)
|
||||||
|
|
||||||
|
list.addFirst(30)
|
||||||
|
expect(list.head()).toBe(30)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Check size', () => {
|
||||||
|
const list = new LinkedList()
|
||||||
|
expect(list.size()).toBe(0)
|
||||||
|
|
||||||
|
list.addLast(10)
|
||||||
|
expect(list.size()).toBe(1)
|
||||||
|
|
||||||
|
list.addLast(20)
|
||||||
|
expect(list.size()).toBe(2)
|
||||||
|
|
||||||
|
list.removeFirst()
|
||||||
|
expect(list.size()).toBe(1)
|
||||||
|
})
|
||||||
|
})
|
Reference in New Issue
Block a user