使用go实现链栈

栈的定义

栈是一种先进后出的数据结构,日常使用较为广泛,可以将其比喻成一个瓶子,先放进去的东西掉在了最下面,所以后放出来,栈一般只提供了两种操作方式,分别为入栈和出栈。栈分为链栈和顺序栈,顺序栈使用数组存储数据,链栈采用单链表村粗数据,我们今天是实现的链栈。

结构定义

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]

个人博客地址:https://vtsqr.xyz

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值