栈
定义
栈是一个后进先出的(Last in first out, LIFO)的线性表,它限定仅在表尾进行删除和插入操作。
关键词
栈顶、栈底
允许插入和删除的一端称为栈顶,另一端称为栈底。
空栈
不包含任何数据元素的栈称为空栈。
栈的插入操作
栈的插入操作,叫作进栈,也称压栈、入栈。
栈的删除操作
栈的删除操作,叫作出栈,也称弹栈。
栈的顺序存储结构
进栈操作示意图:
代码实现
package StackArray
// 栈的接口
type StackArray interface {
// 进栈
Push(data interface{}) bool
// 出栈
Pop() interface{}
// 判断是否满
IsFull() bool
// 判断是否空
IsEmpty() bool
// 获取栈大小
Size() int
// 清空栈
Clear()
}
// 栈的结构
type Stack struct {
// 数据域
dataSource []interface{}
// 最大空间
capsize int
// 当前大小
currentsize int
}
// 初始化栈
func NewStack() *Stack {
// 初始化结构体
mystack := new(Stack)
// 开辟内存空间
mystack.dataSource = make([]interface{}, 0, 10)
// 初始化最大空间
mystack.capsize = 10
// 初始化当前大小
mystack.currentsize = 0
return mystack
}
// 进栈
func (stack *Stack) Push(data interface{}) bool {
// 已满
if stack.IsFull() {
return false
}
// 数据加入到数据域
stack.dataSource = append(stack.dataSource, data)
// 大小加1
stack.currentsize++
return true
}
// 出栈
func (stack *Stack) Pop() interface{} {
// 为空
if stack.IsEmpty() {
return nil
}
// 最后一个元素
last := stack.dataSource[stack.currentsize-1]
// 重设数据域
stack.dataSource = stack.dataSource[:stack.currentsize-1]
// 大小减去1
stack.currentsize--
return last
}
// 判断是否满
func (stack *Stack) IsFull() bool {
return stack.currentsize >= stack.capsize
}
// 判断是否空
func (stack *Stack) IsEmpty() bool {
return stack.currentsize == 0
}
// 获取栈大小
func (stack *Stack) Size() int {
return stack.currentsize
}
// 清空栈
func (stack *Stack) Clear() {
// 重新开辟内存空间
stack.dataSource = make([]interface{}, 0, 10)
// 重新初始化最大空间
stack.capsize = 10
// 重新初始化当前大小
stack.currentsize = 0
}
栈的链式存储结构
链栈绝大部分的操作和单链表类似,所以不再赘述,直接上代码。
代码实现
package StackLink
import "errors"
// 链式栈接口
type StackLink interface {
// 进栈
Push(data interface{})
// 出栈
Pop() (interface{}, error)
// 获取栈长度
Length() int
// 判断是否空
IsEmpty() bool
}
// 链式栈结点
type Node struct {
value interface{}
pNext *Node
}
// 初始化链式栈
func NewStackLink() *Node {
return &Node{}
}
// 进栈(头部插入)
func (n *Node) Push(data interface{}) {
// 新结点
newNode := &Node{
value: data,
// 头结点的指针赋值给新结点的指针
pNext: n.pNext,
}
// 头结点指向新结点
n.pNext = newNode
}
// 出栈
func (n *Node) Pop() (interface{}, error) {
// 链栈为空
if n.IsEmpty() == true {
return nil, errors.New("空链栈")
}
// 获取第一个元素的值
value := n.pNext.value
// 头结点指向原来的第二个元素
n.pNext = n.pNext.pNext
return value, nil
}
// 获取栈长度
func (n *Node) Length() int {
// 备份头结点
pnext := n
// 初始化长度
length := 0
// 循环到末尾
for pnext.pNext != nil {
pnext = pnext.pNext
length++
}
return length
}
// 判断是否空
func (n *Node) IsEmpty() bool {
return n.pNext == nil
}
练习
1. 栈实现递归
实现1+2+3…+5
// 初始化栈
mystack := StackArray.NewStack()
// 保存结果
last := 0
// 压入
mystack.Push(5)
for !mystack.IsEmpty() {
// 取出数据
data := mystack.Pop()
if data == 0 {
last += 0
} else {
last += data.(int)
mystack.Push((data.(int) - 1))
}
}
2. 栈实现斐波拉切数列
// 初始化栈
mystack := StackArray.NewStack()
// 保存结果
last := 0
// 压入
mystack.Push(7)
for !mystack.IsEmpty() {
// 取出数据
data := mystack.Pop()
if data == 1 || data == 2 {
last += 1
} else {
last += data.(int)
mystack.Push((data.(int) - 1))
mystack.Push((data.(int) - 2))
}
}