Singly Circular Linked List

// 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 }
Algerlogo

Β© Alger 2022

About us

We are a group of programmers helping each other build new things, whether it be writing complex encryption programs, or simple ciphers. Our goal is to work together to document and model beautiful, helpful and interesting algorithms using code. We are an open-source community - anyone can contribute. We check each other's work, communicate and collaborate to solve problems. We strive to be welcoming, respectful, yet make sure that our code follows the latest programming guidelines.