栈
一、什么是栈
1. 定义:只允许在一端(栈顶)进行插入和删除操作的线性表。
2. 特点:先进后出。
图示:
二、栈的应用
1. 只要实际问题符合先进后出的特点,即可使用栈进行解决。
2. 栈在计算机科学领域具有广泛的应用,例如,在编译和程序执行过程中,就需要利用栈进行语法检查、计算表达式的值、实现函数或过程的嵌套调用或递归调用。
3. 在一般问题算法设计中的应用也十分广泛,特别是在穷举(遍历或搜索)满足问题部分要求求解的过程中往往需要记录某一阶段穷举的特例,以便无法找到所要结果时能退回去(回溯)重新继续穷举。
三、栈的实现
栈可使用数组或单向线性链表实现,下面分别是这两种实现方式的Go语言代码。
1. 数组栈
/**
* 数组栈
* author:JetWu
* date:2020.02.03
*/
package arrayStack
import (
"errors"
"fmt"
)
/**
* 数组栈结构
**/
type ArrayStack struct {
slice []int
head int //栈顶位置:slice最后一个有效元素的索引位置
}
/**
* 创建空栈
**/
func NewArrayStack() *ArrayStack {
return &ArrayStack{
slice: make([]int, 10),
head: -1,
}
}
/**
* 使用切片创建栈
**/
func MakeArrayStack(slice []int) *ArrayStack {
return &ArrayStack{
slice: slice,
head: len(slice) - 1,
}
}
/**
* 打印栈
**/
func (as *ArrayStack) Print() {
fmt.Println("count:")
fmt.Println(as.Count())
fmt.Println("members:")
for i := as.head; i >= 0; i-- {
fmt.Print(as.slice[i], " ")
}
fmt.Println()
}
/**
* 判断栈是否为空
**/
func (as *ArrayStack) IsEmpty() bool {
return as.head == -1
}
/**
* 栈长度
**/
func (as *ArrayStack) Count() int {
return as.head + 1
}
/**
* 入栈
**/
func (as *ArrayStack) Push(data int) bool {
as.head++
if as.head+1 <= len(as.slice) {
as.slice[as.head] = data
} else {
as.slice = append(as.slice, data)
}
return true
}
/**
* 出栈
**/
func (as *ArrayStack) Pop() (int, error) {
if as.head == -1 {
return 0, errors.New("栈为空")
}
data := as.slice[as.head]
as.head--
return data, nil
}
2. 链表栈
/**
* 链表栈
* author:JetWu
* date:2020.02.03
*/
package listStack
import (
"errors"
"fmt"
)
/**
* 链表栈节点结构
**/
type node struct {
data int
next *node
}
/**
* 链表栈结构
**/
type ListStack struct {
head *node //链表头部,不存储实际数据
}
/**
* 创建空栈
**/
func NewListStack() *ListStack {
return &ListStack{
head: &node{next: nil},
}
}
/**
* 使用切片创建栈
**/
func MakeListStack(slice []int) *ListStack {
ls := NewListStack()
for i := 0; i < len(slice); i++ {
ls.Push(slice[i])
}
return ls
}
/**
* 打印栈
**/
func (ls *ListStack) Print() {
count := 0
ptr := ls.head.next
fmt.Println("members:")
for ptr != nil {
fmt.Print(ptr.data, " ")
count++
ptr = ptr.next
}
fmt.Println()
fmt.Println("count:")
fmt.Println(count)
}
/**
* 判断栈是否为空
**/
func (ls *ListStack) IsEmpty() bool {
return ls.head.next == nil
}
/**
* 栈长度
**/
func (ls *ListStack) Count() int {
count := 0
ptr := ls.head.next
for ptr != nil {
count++
ptr = ptr.next
}
return count
}
/**
* 入栈
**/
func (ls *ListStack) Push(data int) bool {
nod := node{data: data, next: ls.head.next}
ls.head.next = &nod
return true
}
/**
* 出栈
**/
func (ls *ListStack) Pop() (int, error) {
if ls.head.next == nil {
return 0, errors.New("栈为空")
}
data := ls.head.next.data
ls.head.next = ls.head.next.next
return data, nil
}
注:这里栈存储int类型数据,存储其他类型元素可依理类推。