Golang queue data structure implementation

package main

import (
	"container/list"
	"errors"
	"fmt"
)

// Queue is a list data structure that follows First-In-First-Out (FIFO) methodology
type Queue struct {
	size  int       // size of the queue
	items list.List // holds the elements
}

// enqueue() method inserts new element at the back of the queue
func (queue *Queue) enqueue(str string) (bool, error) {
	if queue.items.Len() >= queue.size {
		return false, errors.New("Overflow")
	}
	queue.items.PushBack(str)
	return true, nil
}

// dequeue() method removes element at the front of the queue
func (queue *Queue) dequeue() (string, error) {
	if queue.items.Len() == 0 {
		return "", errors.New("Empty")
	}
	ret := queue.items.Front().Value.(string)
	queue.items.Remove(queue.items.Front())
	return ret, nil
}

func main() {
	queue := &Queue{size: 5}

	fmt.Println(queue.enqueue("1"))
	fmt.Println(queue.dequeue())
	fmt.Println(queue.dequeue())

	fmt.Println(queue.enqueue("1"))
	fmt.Println(queue.enqueue("2"))
	fmt.Println(queue.enqueue("3"))
	fmt.Println(queue.enqueue("4"))
	fmt.Println(queue.enqueue("5"))
	fmt.Println(queue.enqueue("6"))
}

Golang stack implementation

package main

import (
	"container/list"
	"errors"
	"fmt"
)

// Stack is a list that can only perform two operations: push and pop
type Stack struct {
	items list.List
}

// push() method inserts new element at the top of the stack
func (stack *Stack) push(str string) {
	stack.items.PushBack(str)
}

// pop() method removes the element at the top of the stack
func (stack *Stack) pop() (string, error) {
	if stack.items.Back() == nil {
		return "", errors.New("Empty")
	}
	lastVal := stack.items.Back().Value.(string) // get the value of last element
	stack.items.Remove(stack.items.Back())       // remove the last element
	return lastVal, nil
}

func main() {
	stack := &Stack{}
	stack.push("1")
	stack.push("2")
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
	fmt.Println(stack.pop())
}

Golang singly linked list

package main

import "fmt"

// Node can store two values, 'id' and 'name'.
// Another value, 'ptr' is a pointer to another node
type Node struct {
	id   int
	name string
	ptr  *Node
}

// LinkedList struct
type LinkedList struct {
	head *Node
}

// LinkedList method to append a node to tail
func (linkedlist *LinkedList) append(newnode *Node) *LinkedList {
	if linkedlist.head == nil {
		linkedlist.head = newnode
		newnode.ptr = nil
		return linkedlist
	} // else
	// initialization; condition; increment
	for n := linkedlist.head; n != nil; n = n.ptr {
		if n.ptr == nil {
			n.ptr = newnode
			return linkedlist
		}
	}
	return linkedlist
}

// LinkedList method to print the nodes details
func (linkedlist *LinkedList) print() {
	for n := linkedlist.head; n != nil; n = n.ptr {
		fmt.Println(n.id, n.name, n.ptr)
	}
}

// LinkedList method to insert a new node before a particular node
func (linkedlist *LinkedList) insertBefore(name string, newNode *Node) bool {
	if linkedlist.head == nil {
		return false
	}

	ptrNode := linkedlist.head // points to first node
	for ptrNode.ptr != nil {   // while() loop
		if ptrNode.ptr.name == name {
			newNode.ptr = ptrNode.ptr // new node points to the next node
			ptrNode.ptr = newNode     // current node points to the new node
			return true
		}
		ptrNode = ptrNode.ptr // points to next node
	}
	return false
}

func main() {
	// create a linked list object
	linkedlist := &LinkedList{}

	// create nodes
	nodeA := &Node{1, "A", nil}
	nodeB := &Node{2, "B", nil}
	nodeC := &Node{3, "C", nil}
	nodeD := &Node{4, "D", nil}
	nodeE := &Node{5, "E", nil}

	// append the nodes to the linked list
	linkedlist.append(nodeA)
	linkedlist.append(nodeB)
	linkedlist.append(nodeC)
	linkedlist.append(nodeD)
	linkedlist.append(nodeE)

	// print the linked list
	linkedlist.print()

	// create a new node
	nodeF := &Node{6, "F", nil}
	// insert the new node before node "B"
	linkedlist.insertBefore("B", nodeF)
	// print the linked list
	linkedlist.print()
}