--- title: 使用go实现链栈 tags: go,数据结构,链栈 categories: 数据结构 date: 2022-01-09 10:28:29 --- # 栈的定义 栈是一种先进后出的数据结构,日常使用较为广泛,可以将其比喻成一个瓶子,先放进去的东西掉在了最下面,所以后放出来,栈一般只提供了两种操作方式,分别为入栈和出栈。栈分为链栈和顺序栈,顺序栈使用数组存储数据,链栈采用单链表村粗数据,我们今天是实现的链栈。 ## 结构定义 ```go type Stack struct { data interface{} next *Stack size int sync.Mutex } ``` data对应存储数据,next是一个实例指针,指向下面的一个元素,size用来存储栈的大小,其实可有可无,sync.Mutex是解决并发操作的问题。 ## 初始化栈 ```go func newStack() *Stack { s := new(Stack) s.next = nil s.size = 0 return s } ``` 首先创建一个Stack对象,将其next指针域置为nil,size置为0. # 栈的相关操作 ## 入栈 ```go func (s *Stack) push(element interface{}) { s2 := new(Stack) s2.next = s.next s2.data = element s.Lock() s.size ++ s.next = s2 s.Unlock() } ``` 入栈首先创建一个新的节点,然后将节点的指针指向头节点的指向,然后为该节点赋值,然后操纵头节点之前应该上锁,将头节点的size加一,同时头节点的指针指向新创建的节点,最后取消锁。 ## 出栈 ```go func (s *Stack) pop() interface{} { if s.next == nil { return nil } node := s.next s.Lock() s.size -- s.next = node.next s.Unlock() return node.data } ``` 出栈首先判断头节点的指针是否为nil,若为nil则代表栈内没有元素,返回nil值,然后将栈顶节点取出来,然后将头节点的size减一,同时将头节点的指针域指向栈顶节点的下一节点,最后返回栈顶节点的值。 ## 获取栈顶节点的值 ```go func (s *Stack) getTop() interface{} { if s.next == nil { return nil } return s.next.data } ``` 和出栈不一样的地方是,该方法只获取栈顶节点的值,不会删除栈顶节点。 ## 全部出栈转为数组 ```go func (s *Stack) toArray() []interface{} { array:= make([]interface{}, s.size) length := s.size for i := 0; i < length; i++ { array[i] = s.pop() } return array } ``` 其中要将s.size单独取出来,因为在循环过程中出栈,s.size的值会发生改变。 # 测试 ```go func main() { stack := newStack() stack.push(1) stack.push(2) stack.push(3) stack.push(1) stack.push(4) fmt.Println(stack.pop()) fmt.Println(stack.pop()) fmt.Println("栈的剩余元素个数:",stack.size) fmt.Println(stack.toArray()) } // 4 // 1 // 栈的剩余元素个数: 3 // [3 2 1] ``` ## 个人博客地址: