栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。
1、栈顺序存储
1、图解
2、抽象数据类型
// MAXSIZE 定义数组的最大长度
const MAXSIZE = 100
type SqStack struct {
data [MAXSIZE]ElemType //数组用于存放数据
top int //栈顶指针 -1为空栈,正好与数组的下标对应
}
// InitSqStack 初始化栈,(更像是格式化栈)
func InitSqStack(stack *SqStack) {
for i := 0; i < MAXSIZE; i++ {
stack.data[i] = 0
}
stack.top = -1
}
// Push 入栈操作
func Push(stack *SqStack, e ElemType) bool {
if stack.top == MAXSIZE-1 {
fmt.Println("栈满")
return false
}
//不满
stack.top += 1
stack.data[stack.top] = e
return true
}
// Pop 出栈操作,将数据存在e中
func Pop(stack *SqStack, e *ElemType) bool {
if stack.top == -1 {
fmt.Println("栈空")
return false
}
*e = stack.data[stack.top]
//回收数组空间
stack.data[stack.top] = 0
stack.top -= 1
return true
}
// GetTop 用e,返回栈顶元素
func GetTop(stack *SqStack, e *ElemType) bool {
if stack.top == -1 {
fmt.Println("栈空")
return false
}
*e = stack.data[stack.top]
return true
}
2、栈链式存储
1、图解
2、抽象数据类型的实现:
// 栈的链式存储结构的定义
type stackNode struct {
data ElemType //存放的数据
next *stackNode //指向下一个节点
}
// LinkStack 定义栈
type LinkStack struct {
count int //栈中元素的个数
top *stackNode //栈顶指针,指向栈中的第一个元素
}
// LSInit 初始化栈,(其实不用初始化,go语言会默认赋零值)
func LSInit(s *LinkStack) {
s.count = 0
s.top = nil
}
// LSPush 入栈操作
func LSPush(stack *LinkStack, e ElemType) {
node := new(stackNode)
node.data = e
node.next = stack.top
stack.top = node
stack.count += 1
}
// LSPop 出栈操作,数据存储在e中
func LSPop(stack *LinkStack, e *ElemType) bool {
if stack.top == nil {
fmt.Println("栈空")
return false
}
*e = stack.top.data
//指针后移动
stack.top = stack.top.next
stack.count -= 1
return true
}
// LSGetTop 返回栈顶元素
func LSGetTop(stack *LinkStack, e *ElemType) bool {
if stack.top == nil {
fmt.Println("栈空")
return false
}
*e = stack.top.data
return true
}