定义
“栈”是一种“操作受限”即只允许在一端插入和删除数据的线性表;后进者先出,先进者后出。
相较数组和链表,栈带来的只有限制;从功能上数组和链表可以取代栈,但是前者暴露了太多可操作接口,操作上确实灵活自由,但使用时比较不可控,自然也就更容易出错。
分类
顺序栈
数组实现的栈
链式栈
链表实现
相关操作
入栈
出栈
代码实现
package main
import (
"fmt"
)
type ArrayStack struct {
Items []interface{}
Count int
}
// 初始化n大小的栈
func NewStackArr() (arrayStack *ArrayStack) {
arrayStack = &ArrayStack{
Items:[]interface{}{},
Count:-1,
}
return
}
// 入栈
func (this *ArrayStack) PushStack(item interface{}) bool {
if this.Count != len(this.Items)-1 {
this.Count = len(this.Items)-1
}
this.Count++
this.Items = append(this.Items, item)
return true
}
// 出栈
func (this *ArrayStack) PopStack() (item interface{}, err error) {
item = this.Items[this.Count]
this.Items = this.Items[0:this.Count]
this.Count--
return item, err
}
func (this *ArrayStack) IsEmpty() bool {
return this.Count == -1
}
func (this *ArrayStack) Flush() {
this.Items = []interface{}{}
this.Count = -1
//this.N = 0
}
func main() {
arrayStack := NewStackArr()
arrayStack.PushStack(1)
fmt.Printf("arrayStack : %v\n", arrayStack)
arrayStack.PushStack(2)
fmt.Printf("arrayStack : %v\n", arrayStack)
arrayStack.PushStack(3)
fmt.Printf("arrayStack : %v\n", arrayStack)
arrayStack.PushStack(4)
fmt.Printf("arrayStack : %v\n", arrayStack)
item, _ := arrayStack.PopStack()
fmt.Printf("item : %v\n", item)
fmt.Printf("arrayStack pop1: %v\n", arrayStack)
item, _ = arrayStack.PopStack()
fmt.Printf("item : %v\n", item)
fmt.Printf("arrayStack pop2: %v\n", arrayStack)
item, _ = arrayStack.PopStack()
fmt.Printf("item : %v\n", item)
fmt.Printf("arrayStack pop3: %v\n", arrayStack)
item, _ = arrayStack.PopStack()
fmt.Printf("item : %v\n", item)
fmt.Printf("arrayStack pop4: %v\n", arrayStack)
}
时间复杂度
出栈:O(1)
入栈:在栈的容量内,入栈为O(1);在涉及扩容的时候,会从新申请2倍大小内存,从新搬移数据到新内存,在做一次入栈,时间复杂度退化为O(n),用均摊法把最糟糕的时间复杂度巨贪到每个入栈上,也接近O(1),所以入栈时间复杂度为O(1)。
应用
函数调用栈
表达式求值
括号匹配中的应用