How can stacks be implemented in Go
Stack is an abstract data type for data storage. It follows the LIFO or last-in-first-out order for retrieving data. Elements that are added at the end are removed first.
The illustration below shows how a stack works:
Explanation
Step 1: The stack is initially empty
Step 2: A push operation adds an item to the top of the stack. The top shifts one place above its previous position.
Step 3: Each subsequent push adds an item to the top of the stack.
Step 4: A pop command removes an item from the top-1 position of the stack. The top shifts one place below its previous position.
Implementation
Stacks can be implemented using an array or a linked list in Go.
Using an Array
An array is used when the stack is of a fixed size. Items are always added to the top of the stack. A variable known as top is used for this purpose.
The illustration below shows how an array-based stack works:
An array-based stack implementation can be broken down into several functions. The purpose of each function is discussed below:
| Function | Purpose |
|---|---|
Length |
Returns the number of items in the stack |
Push |
Adds a data item to the stack |
Pop |
Removes a data item from the stack |
IsEmpty |
Returns true if the stack is empty. Else, returns false |
Top |
Returns the last added value to the stack but does not remove it |
Print |
Displays all elements of the stack |
Function definitions
The functions used to implement an array-based stack are defined as follows:
func (s *StackInt) IsEmpty() bool {}
func (s *StackInt) Length() int {}
func (s *StackInt) Print() {}
func (s *StackInt) Push(value int) {}
func (s *StackInt) Pop() int {}
func (s *StackInt) Top() int {}
Example
The code below shows an array-based implementation of the stack in Golang:
package mainimport "fmt"type StackInt struct {s []int}// isEmpty() functionfunc (s *StackInt) IsEmpty() bool {length := len(s.s)return length == 0}// length() functionfunc (s *StackInt) Length() int {length := len(s.s)return length}// Print() functionfunc (s *StackInt) Print() {length := len(s.s)for i := 0; i < length; i++ {fmt.Print(s.s[i], " ")}fmt.Println()}// Push() functionfunc (s *StackInt) Push(value int) {s.s = append(s.s, value)}// Pop() functionfunc (s *StackInt) Pop() int {length := len(s.s)res := s.s[length-1]s.s = s.s[:length-1]return res}// Top() functionfunc (s *StackInt) Top() int {length := len(s.s)res := s.s[length-1]return res}func main() {var stack StackInt // create a stack variable of type Stack/* Adding items to stack */stack.Push(1)stack.Push(2)stack.Push(3)fmt.Println("Printng the stack:")stack.Print() // Print the stackfmt.Println("Checking length of stack:")fmt.Println(stack.Length()) // Get Lengthfmt.Println("Removing an Item:")fmt.Println(stack.Pop()) // Remove an itemfmt.Println("Updated Stack:")stack.Print()fmt.Println("Getting last Added Item in Stack")fmt.Println(stack.Top()) // Get last item}
Explanation
- An object of the struct -
StackIntis created namedstack. It refers to our stack array. - The
pushfunction appends the provided value to the stack. In our case, we push three values separately into the stack. - The
lengthfunction returns the number of elements in the stack. - The
popfunction first computes the length of the stack. It then removes the last element and returns it. - The
topfunction first computes the length of the stack. It then returns the last element added to the stack. - The
printfunction iterates over each element and prints it.
Using a Linked List
A stack implemented using a linked list does not have an upper bound on the number of items that can be added. An item is added to the head of the linked list using the push operation. Therefore, with each addition, the head pointer changes. Similarly, the head of the linked list is removed using the pop operation. The head pointer then points to the second node in the linked list.
The illustration below shows how a linked list-based stack works:
A linked list basedstack implementation can be broken down into several functions. The purpose of each function is discussed below:
| Function | Purpose |
|---|---|
Size |
Returns the number of items in the stack |
Push |
Adds a data item to the stack |
Pop |
Removes a data item from the stack |
IsEmpty |
Returns true if the stack is empty. Else, returns false |
Peek |
Returns the value at the top of the linked list but does not remove it |
Print |
Displays all elements of the stack |
Function definitions
The functions used to implement an linked list based stack are defined as follows:
func (s *StackLinkedList) Size() int {}
func (s *StackLinkedList) IsEmpty() bool {}
func (s *StackLinkedList) Peek() (int, bool) {}
func (s *StackLinkedList) Push(value int) {}
func (s *StackLinkedList) Pop() (int, bool) {}
func (s *StackLinkedList) Print() {}
Example
The code below shows a linked list-based implementation of the stack in Golang:
package mainimport "fmt"type Node struct {value intnext *Node}type StackLinkedList struct {head *Nodesize int}// Size() functionfunc (s *StackLinkedList) Size() int {return s.size}// IsEmpty() functionfunc (s *StackLinkedList) IsEmpty() bool {return s.size == 0}// Peek() functionfunc (s *StackLinkedList) Peek() (int) {if s.IsEmpty() {fmt.Println("StackEmptyException")return 0}return s.head.value}// Push() functionfunc (s *StackLinkedList) Push(value int) {s.head = &Node{value, s.head}s.size++}// Pop() functionfunc (s *StackLinkedList) Pop() (int, bool) {if s.IsEmpty() {fmt.Println("StackEmptyException")return 0, false}value := s.head.values.head = s.head.nexts.size--return value, true}// Print() function will print the elements of the linked list. */func (s *StackLinkedList) Print() {temp := s.headfmt.Print("Values stored in stack are: ")for temp != nil {fmt.Print(temp.value, " ")temp = temp.next}fmt.Println()}func main() {var stack StackLinkedList // create a stack variable of type StackLinkedList// Adding items to stackstack.Push(1)stack.Push(2)stack.Push(3)stack.Print() // Print the stackfmt.Println("Checking length of stack:")fmt.Println(stack.Size()) // Get Lengthfmt.Println("Removing an Item:")stack.Pop() // Remove an itemstack.Print()fmt.Println("Getting Item at Top of Linked List")fmt.Println(stack.Peek()) // Get Top-most item}
Explanation
- An object of the struct
StackLinkedListis created namedstack. It refers to a head node and has anintvariable to keep track of the size of the stack. - The
pushfunction creates a new head node. It assigns it theintvalue that is passed in the parameter. In our case, we push three values separately into the stack. - The
lengthfunction returns the number of elements in the stack. - The
popfunction first checks if the stack is empty. It raises an exception in that case. Otherwise, it makes the second node in the linked list the head node and deletes the first node. It also decrements thesizevariable by one. - The
peekfunction returns the value of the head node of the linked list. - The
printfunction iterates over each node and prints its value.
Free Resources