栈和队列

上一篇博客讲了数组和链表,它们有一个很大的区别就是在内存中的存在方式是不同的。数组是连续的,链表是零散的。这种在内存中的存在形式又被称为物理结构数组是顺序存储结构,链表是链式存储结构。除了物理结构之外,还有一个叫做逻辑结构,分为线性结构(顺序表,栈,队列)和非线性结构(树,图)

之所以叫做逻辑结构是因为我们不关心它在内存的存储形式,可能是顺序存储,也可能是链式存储。我们只关心数据结构本身的特性

比如栈和队列的物理实现既可以用数组实现,也能用链表实现
这里我们只关心栈和队形本身的逻辑特性,即栈是先进后出,队列是先进先出

栈的相关概念:

  1. 先进后出
  2. 最早进入的元素存放的位置叫做栈底,最后进入的元素存放的位置叫做栈顶,栈底和栈顶都对应一个元素
  3. 入栈和出栈的时间复杂度都是O(1)的。入栈append很好理解,出栈涉及到slice的截取,在底层实现是数组指针的移动,也是O(1)的

用数组实现栈比较简单,代码如下:

package main

import (
	"errors"
	"fmt"
)

type Stack struct {
	arr       []interface{} //切片
	stackSize int           //栈中元素的个数
}

func NewStack()Stack  {
	stack:=Stack{arr:make([]interface{},0)}
	return stack
}

//push栈元素
func (s *Stack) push(t interface{}) {
	s.arr = append(s.arr, t)
	s.stackSize +=  1
}

//pop栈元素
func (s *Stack) pop() interface{} {
	if s.stackSize > 0 { //栈不为空时
		s.stackSize--
		element := s.arr[s.stackSize]
		s.arr = s.arr[:s.stackSize]
		return element
	}
	return errors.New("栈为空")
}
func main()  {
	stack:=NewStack()
	stack.push(8)
	fmt.Println(stack.pop())

}


队列的相关概念:

  1. 先进先出
  2. 队列的出口端叫做队头,队列的入口端叫做队尾
  3. 入列和出列的时间复杂度都是O(1)的。入列append很好理解,出列涉及到slice的截取,在底层实现是数组指针的移动,也是O(1)的
package main

import (
	"errors"
	"fmt"
)

// 队列,以切片的最后一个元素为对头,第一个元素为队尾
type Queen struct {
	arr       []interface{} //切片
	stackSize int           //栈中元素的个数
}

func NewQueen()Queen  {
	stack:=Queen{arr:make([]interface{},0)}
	return stack
}

//push队列元素
func (s *Queen) push(t interface{}) {
	s.arr = append(s.arr, t)
	s.stackSize +=  1
}

//pop队列元素
func (s *Queen) pop() interface{} {
	if s.stackSize > 0 { //队列不为空时
		element := s.arr[0]
		s.arr = s.arr[1:s.stackSize]
		s.stackSize--
		return element
	}
	return errors.New("队列为空")
}
func main()  {
	stack:=NewQueen()
	stack.push(8)
	fmt.Println(stack.pop())

}


参考资料:
Go 数据结构和算法篇(二):栈

Go 数据结构和算法篇(三):队列

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值