栈(Stack)是一种操作受限的线性数据结构,遵循后进先出(LIFO)原则,使用Go语言实现顺序存储的栈,本质是通过数组或切片在内存中分配连续空间进行数据存储,以下是完整实现方案,包含初始化、入栈、出栈等核心操作,并附有动态扩容策略与错误处理机制。
通过结构体封装栈的属性和方法,包含存储数据的切片、栈顶指针和容量控制字段:
type ArrayStack struct { data []int // 存储元素的切片 top int // 栈顶指针(当前元素索引) capacity int // 栈容量 }
top
指针初始值为-1
,表示空栈状态;capacity
用于限制栈的最大容量(若需无限容量可移除该字段)。
提供两种初始化方式:固定容量栈和动态扩容栈。
// 创建固定容量栈 func NewFixedStack(capacity int) *ArrayStack { return &ArrayStack{ data: make([]int, capacity), top: -1, capacity: capacity, } } // 创建动态扩容栈(初始容量为10) func NewDynamicStack() *ArrayStack { return &ArrayStack{ data: make([]int, 0, 10), top: -1, capacity: 10, } }
当栈空间不足时触发动态扩容,容量扩展为原来的2倍:
func (s *ArrayStack) Push(val int) error { if s.IsFull() { if s.capacity == 0 { // 处理初始容量为0的情况 s.capacity = 1 s.data = make([]int, 1) } else { newCapacity := s.capacity * 2 newData := make([]int, newCapacity) copy(newData, s.data) s.data = newData s.capacity = newCapacity } } s.top++ if s.top >= len(s.data) { s.data = append(s.data, val) } else { s.data[s.top] = val } return nil }
返回栈顶元素并移动指针,处理空栈错误:
func (s *ArrayStack) Pop() (int, error) { if s.IsEmpty() { return 0, fmt.Errorf("栈为空") } val := s.data[s.top] s.top-- return val, nil }
func (s *ArrayStack) Peek() (int, error) { if s.IsEmpty() { return 0, fmt.Errorf("栈为空") } return s.data[s.top], nil }
func (s *ArrayStack) IsEmpty() bool { return s.top == -1 } func (s *ArrayStack) IsFull() bool { return s.top == s.capacity-1 } func (s *ArrayStack) Size() int { return s.top + 1 }
动态扩容策略
当切片容量不足时,自动扩容为当前容量的2倍(时间复杂度摊还分析为O(1)
)。
内存预分配
初始化时通过make([]int, 0, initialCapacity)
预先分配内存,减少后续扩容次数。
缩容机制(可选)
当栈大小不足容量的1/4时,可将容量减半以避免内存浪费。
验证栈的基础功能:
func main() { stack := NewDynamicStack() stack.Push(10) stack.Push(20) topVal, _ := stack.Peek() fmt.Println("栈顶元素:", topVal) // 输出 20 val, _ := stack.Pop() fmt.Println("弹出元素:", val) // 输出 20 fmt.Println("当前栈大小:", stack.Size()) // 输出 1 }
对比维度 | 顺序栈 | 链式栈 |
---|---|---|
内存占用 | 预先分配固定空间 | 动态分配,额外指针 |
扩容成本 | 需整体迁移数据 | 只需修改指针 |
访问速度 | CPU缓存友好,访问速度快 | 内存分散,访问较慢 |
适用场景 | 元素数量可预估 | 元素数量波动大 |
本文实现参考《算法导论》栈结构设计原则,并遵循Go语言官方文档切片操作规范,动态扩容策略采用计算机科学中常见的摊还分析理论。