Go数据结构----队列操作

四、实现数组队列ArrayQueue

队列先进先出,和栈操作顺序相反,我们这里只实现入队,和出队操作,其他操作和栈一样。

package main

import "sync"

// 数组队列,先进先出
type ArrayQueue struct {
	array []string   //底层切片
	size  int        //队列元素的数量
	lock  sync.Mutex //为了并发安全使用的锁
}

// 入队操作
func (queue *ArrayQueue) Add(v string) {
	queue.lock.Lock()
	defer queue.lock.Unlock()
	//放入切片中,后进的元素放在数组最后面
	queue.array = append(queue.array, v)
	//队中元素数量+1
	queue.size += 1

}

//直接将元素放在数组最后面即可,和栈一样,时间复杂度为:O(n)。

//出队操作

func (queue *ArrayQueue) Pop() string {
	queue.lock.Lock()
	queue.lock.Unlock()
	//如果队列为空的话
	if queue.size == 0 {
		panic("队列已空")
	}
	//取出队列最前端的数据,但你要考了不后续元素补位问题
	v := queue.array[0]
	/*相当于处理方式1
	直接原位进行移动,但缩容的后续的空间不会被释放
	for i := 0; i < queue.size; i++ {
			//从第一位开始进行数据移动操作
			queue.array[i-1]=queue.array[i]
		}
		//并且原数组缩容
		queue.array=queue.array[0:queue.size-1]
	*/

	//下面使用第二种开辟新数组进行操作
	newArray := make([]string, queue.size-1, queue.size-1)
	for i := 1; i < queue.size; i++ {
		//从原数组的第一位进行开始数据移动
		newArray[i-1] = queue.array[i]
	}
	queue.array = newArray
	//然后队中元素数量-1
	queue.size = queue.size - 1
	return v
}
func main() {

}

注意:

出队,把数组的第一个元素的值返回,并对数据进行空间挪位,挪位有两种:

  1. 原地挪位,依次补位 queue.array[i-1] = queue.array[i],然后数组缩容:queue.array = queue.array[0 : queue.size-1],但是这样切片缩容的那部分内存空间不会释放。
  2. 创建新的数组,将老数组中除第一个元素以外的元素移动到新数组。

时间复杂度是:O(n)

五、实现链表队列LinkQueue

​ 队列先进先出,和栈操作顺序相反,无非和上述实现方式不一样罢了

package main

import "sync"

//链表队列,先进先出

type LinkQueue struct {
	root *LinkNode //链表起点
	size int
	lock sync.Mutex
}
type LinkNode struct {
	next  *LinkNode
	Value string
}

// 入队操作
func (queue *LinkQueue) Add(v string) {
	queue.lock.Lock()
	defer queue.lock.Unlock()
	//如果栈为空,就进行增加节点操作
	if queue.root == nil {
		queue.root = new(LinkNode)
		queue.root.Value = v
	} else {
		//如果不为空,将新元素加入到我们的链表的末尾
		//新节点的创建
		newNode := new(LinkNode)
		newNode.Value = v
		// 一直遍历到链表尾部
		nowNode := queue.root
		for nowNode.next != nil {
			newNode = nowNode.next
		}
		//然后将新节点放在链表末尾
		nowNode.next = newNode
	}
	//队中元素数量+1
	queue.size = queue.size + 1
}

//将元素放在链表的末尾,所以需要遍历链表,时间复杂度为:O(n)。

//出队操作
func (queue *LinkQueue) Remove() string {
	queue.lock.Lock()
	defer queue.lock.Unlock()

	//队列元素已为空
	if queue.size == 0 {
		panic("队列为空")
	}
	//出队操作

	topNode := queue.root
	v := topNode.Value

	//然后将顶部元素的后续链接连接上
	queue.root = topNode.next
	//并且队中元素数量-1
	queue.size = queue.size - 1

	return v

}
//链表第一个节点出队即可,时间复杂度为:O(1)。
func main() {

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值