Created
November 6, 2022 13:12
-
-
Save MAVERICK6912/33c14687a343879d6413dbbc266180b1 to your computer and use it in GitHub Desktop.
Implementation of custom Circular linkedlist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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