124 lines
2.7 KiB
Markdown
124 lines
2.7 KiB
Markdown
---
|
||
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]
|
||
|
||
```
|
||
|
||
## 个人博客地址:<https://vtsqr.xyz> |