栈是一种先进后出的线性表,简称LIFO。因为在Golang中数组定义后长度不可以改变,因此这里通过切片实现栈操作。栈和队列的操作很相似,但是队列是先进先出的。
定义结构体,并创建栈,初始化空栈
type SliceStack struct {
data []interface{} //存储栈数据切片
size int //栈中元素个数
}
// 创建栈
func newSliceStack() *SliceStack {
return &SliceStack{make([]interface{}, 0), 0}
}
IsEmpty方法 判断栈是否为空; IsSize方法 返回栈中元素的个数
func (s *SliceStack) IsEmpty() bool {
return s.size == 0
}
func (s *SliceStack) IsSize() int {
return s.size
}
Pot方法 返回栈顶元素,栈先进后出因此返回栈最后进入的元素。
func (s *SliceStack) Pot() interface{} {
if s.IsEmpty() {
return nil
}
return s.data[s.size-1]
}
两种入栈操作,这里和队列的入队列操作一样。第一种是一个一个添加;第二种一次性添加多个元素。
func (s *SliceStack) Push(v interface{}) {
s.data = append(s.data, v)
s.size++
}
func (s *SliceStack) Pushs(v ...interface{}) {
for _, k := range v {
s.Push(k)
}
}
Pop方法实现出栈操作,每次返回栈尾元素。
func (s *SliceStack) Pop() interface{} {
if s.IsEmpty() {
return nil
}
s.size--
fmt.Println("栈中剩余元素个数", s.size)
v := s.data[s.size]
s.data = s.data[:s.size]
fmt.Println("出栈元素为:", v)
return v
}
Peek方法实现显示栈中元素操作,先判断栈是否为空栈,然后通过for...range...循环出栈。
func (s *SliceStack) Peek() {
if s.IsEmpty() {
fmt.Println("空栈")
return
}
fmt.Println("当前栈中元素为:")
for k, v := range s.data {
fmt.Println("k:", k, "v:", v)
}
}
主函数
func main() {
sliceStack := newSliceStack()
sliceStack.Pushs(1)
sliceStack.Pushs(2)
sliceStack.Pushs(3, "4", "你好i")
sliceStack.Peek()
fmt.Println("栈中元素个数:", sliceStack.size)
sliceStack.Pop()
fmt.Println("栈顶元素为:", sliceStack.Pot())
}
整体程序运行结果