Skip to content

Instantly share code, notes, and snippets.

@MAVERICK6912
Created November 6, 2022 13:12
Show Gist options
  • Save MAVERICK6912/33c14687a343879d6413dbbc266180b1 to your computer and use it in GitHub Desktop.
Save MAVERICK6912/33c14687a343879d6413dbbc266180b1 to your computer and use it in GitHub Desktop.
Implementation of custom Circular linkedlist
package main
import (
"errors"
"fmt"
)
type CLLNode struct {
data int
next *CLLNode
}
type CircularLinkedlist struct {
head *CLLNode
tail *CLLNode
size int
}
func (c *CircularLinkedlist) Insert(newNode *CLLNode) {
// checking if linkedlist is empty
if c.size == 0 && c.head == nil {
// since the linkedlist is empty we make the newNode both head and tail
// this is because newNode will be the only node in linkedlist
c.head = newNode
c.tail = newNode
} else {
// while inserting at the end
// make current tail's next point to newNode
c.tail.next = newNode
// make newNode the tail of linkedlist
c.tail = newNode
// make new tail's next point to head of linkedlist
c.tail.next = c.head
}
// finally increase size of linkedlist by one
c.size += 1
}
// isInRange checks if passed index is +ve and less than or equal to current size of linkedlist
func (c *CircularLinkedlist) isInRange(index int) bool {
return index >= 0 && index <= c.size
}
func (c *CircularLinkedlist) InsertAt(index int, newNode *CLLNode) error {
// checking if index is out of bounds.
if !c.isInRange(index) {
return errors.New("Index out of bounds")
}
// insertion at the start of linkedlist
if index == 0 {
// make newNode's next to point to current head of linkedlist
newNode.next = c.head
// make newNode head of linkedlist
c.head = newNode
// make tail's next point to the new head of linkedlist
c.tail.next = c.head
// increase size by one
c.size += 1
// return nil error
return nil
}
// insertion at last of linkedlist
if index == c.size {
// make current tail's next point to newNode
c.tail.next = newNode
// make newNode tail of linkedlist
c.tail = newNode
// make new tail to point to head of inkedlist
c.tail.next = c.head
// increase size by one
c.size += 1
// return nil error
return nil
}
// inserting somewhere in middle
// finding previousNode for the given insertion index
currNode := c.head
var previousNode *CLLNode
for i := 0; i != index; i, currNode = i+1, currNode.next {
previousNode = currNode
}
// make newNode's next point to previousNode's next
newNode.next = previousNode.next
// make previousNode's next to point to newNode
previousNode.next = newNode
// increase size by one
c.size += 1
// return nil error
return nil
}
func (c *CircularLinkedlist) Get(index int) (int, error) {
// checking if index is out of bounds of linkedlist
if !c.isInRange(index) {
return -1, errors.New("Index out of bounds")
}
// find the node at the passed index
currNode := c.head
for i := 0; i != index; i, currNode = i+1, currNode.next {
}
// return data at passed index and nil error
return currNode.data, nil
}
func (c *CircularLinkedlist) RemoveAt(index int) error {
// checking if index is out of bounds of linkedlist
if !c.isInRange(index) {
return errors.New("Index out of bounds")
}
// find previous node of the given index
currNode := c.head
var previousNode *CLLNode
for i := 0; i != index; i, currNode = i+1, currNode.next {
previousNode = currNode
}
if currNode == c.head {
// if deletion node is head of linkedlist
// make head of linkedlist to point to currNode's next
c.head = currNode.next
// make tail's next to point to new head
c.tail.next = c.head
} else if currNode == c.tail {
// if deletion node is tail of linkedlist
// make previousNode the tail of linkedlist
c.tail = previousNode
// make new tail's next to point to head of linkedlist
c.tail.next = c.head
} else {
// deleting anywhere else in the linkedlist
// make previousNode's next to point to currNode's next
previousNode.next = currNode.next
}
// finally decrease size by one and return nil error
c.size -= 1
return nil
}
func main() {
firstNodeToInsert := &CLLNode{
data: 12,
}
secondNodeToInsert := &CLLNode{
data: 123,
}
thirdNodeToInsert := &CLLNode{
data: 1234,
}
fourthNodeToInsert := &CLLNode{
data: 12345,
}
cll := CircularLinkedlist{}
fmt.Println("inserting first node.........")
cll.Insert(firstNodeToInsert)
fmt.Println("inserting second node.........")
cll.Insert(secondNodeToInsert)
fmt.Println("inserting third node.........")
cll.Insert(thirdNodeToInsert)
fmt.Println("inserting another node at position 2.........")
cll.InsertAt(1, fourthNodeToInsert)
val, err := cll.Get(0)
fmt.Println("element at first position: ", val, " and error was: ", err)
val, err = cll.Get(1)
fmt.Println("element at second position: ", val, " and error was: ", err)
val, err = cll.Get(2)
fmt.Println("element at third position: ", val, " and error was: ", err)
val, err = cll.Get(3)
fmt.Println("element at fourth position: ", val, " and error was: ", err)
fmt.Println("passing random index not in bounds of linkedlist.........")
val, err = cll.Get(57)
fmt.Println("element at first position: ", val, " and error was: ", err)
// removing node at index 2
fmt.Println("removing node at index 2.........")
cll.RemoveAt(2)
fmt.Println("getting node at index 2.........")
val, err = cll.Get(2)
fmt.Println("element at third position: ", val, " and error was: ", err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment