前言
- 最近开始学算法了,这算是学习笔记。
- 这篇博客主要讲了栈和队列的实现及用法。
- 本文引用资料《Hello 算法》。
一、栈的基础
1.什么是栈?
- 栈(stack)是一种遵循先入后出逻辑的线性数据结构。
- 我们可以把栈想象成一叠盘子,如果要取出最下面的盘子,我们得先取出最上面的盘子。也就是说栈有个特点是先进后出。
- 我们把堆叠元素的顶部称为“栈顶”,底部称为“栈底”。将把元素添加到栈顶的操作叫作“入栈”,删除栈顶元素的操作叫作“出栈”。

(图引自《Hello 算法》)
2.栈的基本操作:
a.初始化栈:
var stack []int
b.元素入栈:
stack = append(stack, 1)
stack = append(stack, 3)
stack = append(stack, 2)
stack = append(stack, 5)
stack = append(stack, 4)
c.访问栈顶元素:
peek := stack[len(stack)-1]
e.元素出栈:
pop := stack[len(stack)-1]
stack = stack[:len(stack)-1]
f.元素出栈:
size := len(stack)
g.判断是否为空:
isEmpty := len(stack) == 0
二、栈的实现
1.基于链表的实现:
- 使用链表实现栈时,我们可以将链表的头节点视为栈顶,尾节点视为栈底。
- 对于入栈操作,我们只需将元素插入链表头部,这种节点插入方法被称为“头插法”。而对于出栈操作,只需将头节点从链表中删除即可。
type linkedListStack struct {
data *list.List
}
func newLinkedListStack() *linkedListStack {
return &linkedListStack{
data: list.New(),
}
}
func (s *linkedListStack) push(value int) {
s.data.PushBack(value)
}
func (s *linkedListStack) pop() any {
if s.isEmpty() {
return nil
}
e := s.data.Back()
s.data.Remove(e)
return e.Value
}
func (s *linkedListStack) peek() any {
if s.isEmpty() {
return nil
}
e := s.data.Back()
return e.Value
}
func (s *linkedListStack) size() int {
return s.data.Len()
}
func (s *linkedListStack) isEmpty() bool {
return s.data.Len() == 0
}
func (s *linkedListStack) toList() *list.List {
return s.data
}
- 代码源自《Hello 算法》。
- 如果对
list
包不熟悉可以看看我主页关于list
包的讲解。
2.基于数组的实现:
- 使用数组实现栈时,我们可以将数组的尾部作为栈顶。
- 入栈与出栈操作分别对应在数组尾部添加元素与删除元素。
- 由于入栈的元素可能会源源不断地增加,因此我们可以使用动态数组,这样就无须自行处理数组扩容问题。
type arrayStack struct {
data []int
}
func newArrayStack() *arrayStack {
return &arrayStack{
data: make([]int, 0, 16),
}
}
func (s *arrayStack) size() int {
return len(s.data)
}
func (s *arrayStack) isEmpty() bool {
return s.size() == 0
}
func (s *arrayStack) push(v int) {
s.data = append(s.data, v)
}
func (s *arrayStack) pop() any {
val := s.peek()
s.data = s.data[:len(s.data)-1]
return val
}
func (s *arrayStack) peek() any {
if s.isEmpty() {
return nil
}
val := s.data[len(s.data)-1]
return val
}
func (s *arrayStack) toSlice() []int {
return s.data
}
结语
- 两种实现是有各自的优缺的,建议大家看看《Hello 算法》这本书里的讲解。这里是对栈的基础讲解,就不多赘述了。
- 浏览器中的后退与前进、软件中的撤销与反撤销;程序内存管理等等,都是由栈实现的。
- 《Hello 算法》对栈的讲解。
- 文章到这里就结束了,希望能够帮助你。