Stack Data Structure in Go

A stack is a Last In First Out (LIFO) data structure, which means that the last element added to the stack will be the first one to be removed. Think of it as a stack of plates; you can only add (push) or remove (pop) a plate from the top of the stack.

Advantages of Stack:

  1. Simple Structure: Stacks are easy to understand and implement.

  2. Fast Operations: The basic operations (push and pop) are O(1) which means they are very fast.

  3. Memory: As elements are added and removed only from one end, there's no need to resize or shift elements frequently.

  4. Useful for Reversals: They are handy for algorithms which need to reverse data, like backtracking algorithms or undo functionality.

  5. Function Calls: Stacks are used in low-level system processes such as managing function calls (call stack).

Disadvantages of Stack:

  1. Limited Size: In some implementations, the size of the stack might be limited.

  2. Memory Overflow: If we try to push elements onto a stack that's already full, it may result in a stack overflow.

  3. Single-ended Operations: Operations are restricted to one end which can be limiting in some scenarios.

  4. Data Retrieval: Retrieving data not on the top can be cumbersome or slow since you have to pop all the elements above it first.

Exercise

Problem: Implement a simple stack in Go. This stack should have the following methods:

  1. Push - To add an element to the top of the stack.

  2. Pop - To remove and return the top element from the stack.

  3. Peek - To view the top element without removing it.

Solution:

package main

import (
    "errors"
    "fmt"
)

type Stack []interface{}

func (s *Stack) Push(value interface{}) {
    *s = append(*s, value)
}

func (s *Stack) Pop() (interface{}, error) {
    if s.IsEmpty() {
        return nil, errors.New("stack is empty")
    }

    length := len(*s)
    elem := (*s)[length-1]
    *s = (*s)[:length-1]
    return elem, nil
}

func (s *Stack) Peek() (interface{}, error) {
    if s.IsEmpty() {
        return nil, errors.New("stack is empty")
    }

    return (*s)[len(*s)-1], nil
}

func (s *Stack) IsEmpty() bool {
    return len(*s) == 0
}

func main() {
    var s Stack
    s.Push(1)
    s.Push(2)
    s.Push(3)

    fmt.Println(s)  // [1 2 3]

    top, _ := s.Peek()
    fmt.Println(top)  // 3

    elem, _ := s.Pop()
    fmt.Println(elem)  // 3
    fmt.Println(s)  // [1 2]
}

The above program demonstrates the simple implementation of a stack in Go with basic stack operations.

References

  1. Stack Data Structure

  2. Stack Abstract Data Type