go语言通过数组和链表的方式实现队列

3 篇文章 0 订阅
3 篇文章 0 订阅

一、什么是队列?
队列是一种特殊的线性表,只能在队列的尾部添加元素,在队列的头部删除元素,先进先出(FIFO)

二、代码实现

type Queue interface {
	Offer(e interface{}) /*队列尾部插入元素*/

	Poll() interface{} /*删除并返回队列前端元素*/

	Peek() interface{} /*返回队列前端元素*/

	Clear() /*清空队列*/

	Size() int /*队列长度*/

	IsEmpty() bool /*判断队列是否为空*/

	Print()/*打印队列元素*/
}

/*通过数组实现队列*/
type ArrayList struct {
	e []interface{}
}

/*初始化-*/
func NewArryList() *ArrayList {
	return &ArrayList{}
}

func (queue *ArrayList) Offer(e interface{}) {
	queue.e = append(queue.e,e)
}

func (queue *ArrayList) Poll() interface{}  {
	if queue.IsEmpty() {
		fmt.Println("queue is empty")
		return nil
	}
	firstE := queue.e[0]
	queue.e = queue.e[1:]
	return firstE
}

func (queue *ArrayList) Peek() interface{}  {
	if queue.IsEmpty() {
		fmt.Println("queue is empty")
		return nil
	}
	return queue.e[0]
}

func (queue *ArrayList) IsEmpty() bool {
	return len(queue.e) == 0
}

func (queue *ArrayList) Size() int {
	return len(queue.e)
}

func (queue *ArrayList) Clear()  {
	if queue.IsEmpty() {
		return
	}
	for i := 0 ; i< len(queue.e) ; i++ {
		queue.e[i] = nil
	}
	queue.e = nil
}

func (queue *ArrayList) Print()  {
	if queue.IsEmpty() {
		return
	}
	for i := 0 ; i< len(queue.e) ; i++ {
		fmt.Print(queue.e[i]," ")
	}
	fmt.Println()
}


type LinkedList struct{
	e interface{}
	next *LinkedList     /*下一个节点*/
	previous *LinkedList /*上一个节点*/
	size int
	last *LinkedList /*最后一个节点*/
}

/*初始化*/
func NewLinkedList() *LinkedList {
	return &LinkedList{}
}

func (node *LinkedList) Offer(e interface{}) {
	node.size += 1
	if node.e == nil {
		node.e = e
		node.last = node
		return
	}
	newNode := &LinkedList{
		e:        e,
		next:     nil,
		previous: node.last,
		size:     node.size,
		last:     nil,
	}
	node.last.next = newNode
	node.last = newNode

}

func (node *LinkedList) Poll() interface{} {
	if node.IsEmpty() {
		return nil
	}
	firstE := node.e
	if node.next != nil {
		lastNode := node.last
		node.next.size = node.size -1
		node.next.previous = nil
		*node = *node.next
		if node.size == 1 {
		/*只有两个节点,移除头节点,剩下一个节点,指针指向第二个节点,最后一个结点,也就是头节点本身*/
			node.last = node
		}else {
			node.last = lastNode
		}

	}else {
		var nilNode LinkedList
		*node = nilNode
	}
	return firstE
}

func (node *LinkedList) Peek() interface{} {
	return node.e
}

func (node *LinkedList) Clear() {
	/*gc采用三色标记算法,传统标记清楚算法,指针指向nil,等待gc回收*/
	var nilNode LinkedList
	p := node
	for p != nil {
		temp := p
		p.e = nil
		p.previous = nil
		p = p.next
		*temp = nilNode
	}
	*node = nilNode
}

func (node *LinkedList) Size() int {
	return node.size
}

func (node *LinkedList) IsEmpty() bool {
	return node.size == 0
}

func (node *LinkedList) Print() {
	p := node
	for p != nil {
		fmt.Print(p.e," ")
		p = p.next
	}
	fmt.Println()
}

三、数组实现和链表实现的对比
3.1 数组实现
优点:数据结构简单,在内存中连续存贮,占用字节少,遍历比较快
缺点:每次添加和删除元素改变数组长度,都要构建新的数组,开销比较大
3.2 链表实现
优点:数据结构复杂,占用字节数相比数组结构较多,添加和删除简单方便,只用移动指针就好
缺点:遍历比较慢,应为要通过指针去寻址,指针对象也要占用一定的内存空间

ps: 有不正确的地方欢迎指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值