[Golang] struct配合slice实现循环队列

循环队列

  • 特征
      使用的头尾索引永远都在底层数组长度下标范围内,如队列长度为10,那么底层数组长度为11,index范围[0,10]
  • 解决的问题
      用非循环数组实现的队列在底层数组满的时候有数据搬移的操作,会影响入队操作;循环数组可以解决这个问题!
  • 与同样用数组实现的普通队列的区别
       1. 循环队列需要专门占用数组的一个位置来作为尾结点标识,这个位置不能填充真实数据,所以实际使用的数组长度会加一。
       2. 循环队列需要一个初始化方法,使用一个默认字符将底层数组初始化。
       3. 循环队列在满队列时,在底层没有数据搬移操作,入队 T(n)=O(1)。
  • Code
package main

import (
	"fmt"
	"strconv"
)

type LoopQueue struct {
	Items 	[]string //利用数组实现队列
	Head 	uint16	 //头索引,恒为0
	Tail	uint16	 //尾索引
	Len 	uint16   //限定队列长度
}


//队列初始化,将[底层数组]初始化
func (this *LoopQueue) Init() {
	this.Len = this.Len + 1 //因为最后一个位置不能使用,所以len要比声明的大一
	for i:=0;i<int(this.Len);i++ {
		this.Items = append(this.Items, "")
	}
}

//入列
func (this *LoopQueue) Enqueue(v interface{}){
	if ((this.Tail+1) % this.Len) == this.Head {
		fmt.Println("the queue is full!")
		return
	}
	this.Items[this.Tail] = v.(string)
	fmt.Printf("%s enqueued, now length: tail:%s \n",v, this.Tail)
	this.Tail = (this.Tail+1) % this.Len
}

//出列
func (this *LoopQueue) Dequeue()interface{}{
	if this.Head == this.Tail {
		fmt.Println("the queue is empty!")
		return nil
	}
	ret := this.Items[this.Head]
	fmt.Printf("Dequeue: %s! the surplus len: head:%s \n", ret, this.Head)
	this.Head = (this.Head+1) % this.Len

	return ret
}




func main(){
	Q := &LoopQueue{Len:10}  //设定队列长度

	Q.Init()  //初始化队列

	for i:=0;i<12;i++ { //12>10 会提示full
		s := strconv.Itoa(i)
		Q.Enqueue(s+s+s)  //入列(但只能入10个)
	}

	for i:=0;i<3;i++ {
		Q.Dequeue() //出列3个
	}

	for i:=0;i<12;i++ { //12>10 会提示full
		s := strconv.Itoa(i)
		Q.Enqueue(s+s+s)  //入列12个(但只能入3个)
	}

	for i:=0;i<12;i++ {
		Q.Dequeue()  //出列12次(但只能出10个)
	}
}

使用这种方式有个问题是,使用队列前需要调用一个初始化方法,且初始化方法时用一个默认字符将底层数组填满,实在不是一个好的办法。读者如有更好的想法,还请指教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值