2.7 KiB
2.7 KiB
title | tags | categories | date |
---|---|---|---|
使用go实现链栈 | go,数据结构,链栈 | 数据结构 | 2022-01-09 10:28:29 |
栈的定义
栈是一种先进后出的数据结构,日常使用较为广泛,可以将其比喻成一个瓶子,先放进去的东西掉在了最下面,所以后放出来,栈一般只提供了两种操作方式,分别为入栈和出栈。栈分为链栈和顺序栈,顺序栈使用数组存储数据,链栈采用单链表村粗数据,我们今天是实现的链栈。
结构定义
type Stack struct {
data interface{}
next *Stack
size int
sync.Mutex
}
data对应存储数据,next是一个实例指针,指向下面的一个元素,size用来存储栈的大小,其实可有可无,sync.Mutex是解决并发操作的问题。
初始化栈
func newStack() *Stack {
s := new(Stack)
s.next = nil
s.size = 0
return s
}
首先创建一个Stack对象,将其next指针域置为nil,size置为0.
栈的相关操作
入栈
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加一,同时头节点的指针指向新创建的节点,最后取消锁。
出栈
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减一,同时将头节点的指针域指向栈顶节点的下一节点,最后返回栈顶节点的值。
获取栈顶节点的值
func (s *Stack) getTop() interface{} {
if s.next == nil {
return nil
}
return s.next.data
}
和出栈不一样的地方是,该方法只获取栈顶节点的值,不会删除栈顶节点。
全部出栈转为数组
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的值会发生改变。
测试
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]