2 Star 4 Fork 0

lsy/data-structure

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
loop_queue.go 3.04 KB
一键复制 编辑 原始数据 按行查看 历史
shouyu.li 提交于 2020-02-21 17:54 +08:00 . 修改包名
package queue
import (
"fmt"
"gitee.com/kklt1996/data-structure/common"
)
/*
front->item->item->tail 元素个数为3
item->tail->front-item 元素个数为3
循环队列,循环队列的好处是增加和删除元素的渐进时间复杂度都是O(1)
*/
type LoopQueue struct {
/*
存放数据的数组
*/
data []interface{}
/*
队首和队尾index的标记
*/
front, tail int
/*
循环队列中元素的个数.
size可以使用front和tail计算出来。但是维护一个size会减少一些计算逻辑
*/
size int
}
/*
~=O(1)
循环队列的进队操作
*/
func (l *LoopQueue) Enqueue(item interface{}) {
// 当队尾位置+1对数组的容量取余等于队首的时候表示循环队列已经满了
// 或者直接使用GetSize()==GetCapacity(),元素个数等于容量.
if (l.tail+1)%cap(l.data) == l.front {
// 容量扩充为原来的2倍
l.resize(l.GetCapacity() * 2)
}
// 赋值最后一个元素
l.data[l.tail] = item
// tail+1对cap取余
l.tail = (l.tail + 1) % cap(l.data)
// 数组容量加1
l.size++
}
/**
~=O(1)
*/
func (l *LoopQueue) Dequeue() (interface{}, error) {
if l.IsEmpty() {
return nil, common.IndexError{}
}
// 先获取出队的元素
dequeueItem := l.data[l.front]
// 避免内存占用
l.data[l.front] = nil
// 队首位置+1对容量取余
l.front = (l.front + 1) % cap(l.data)
// 元素个数-1
l.size--
// 如果元素个数等于当前总容量的四分之一的时候进行缩容操作,容量缩小一半,避免复杂度的震荡.且容量的最小大小不是0
if l.size <= l.GetCapacity()/4 && l.GetCapacity()/2 != 0 {
// 缩容为当前大小的1/2倍,也是当前容量的一半
l.resize(l.GetCapacity() / 2)
}
return dequeueItem, nil
}
func (l *LoopQueue) GetFront() (interface{}, error) {
if l.IsEmpty() {
return nil, common.IndexError{}
}
return l.data[l.front], nil
}
/*
循环队列中元素的个数
*/
func (l *LoopQueue) GetSize() int {
return l.size
}
/*
当队首和队尾相等的时候循环队列是空的
*/
func (l *LoopQueue) IsEmpty() bool {
return l.front == l.tail
}
func (l *LoopQueue) String() string {
res := fmt.Sprintf("Queue: size = %d , capacity = %d ", l.size, l.GetCapacity())
res += "["
// 使用另一种方式遍历循环队列
for i := l.front; i != l.tail; i = (i + 1) % cap(l.data) {
res += fmt.Sprintf("%v", l.data[i])
// 最后一个元素不带,
if (i+1)%cap(l.data) != l.tail {
res += ", "
}
}
res += "]"
return res
}
/*
获取循环队列的容量
*/
func (l *LoopQueue) GetCapacity() int {
return cap(l.data) - 1
}
func (l *LoopQueue) resize(newCapacity int) {
// 创建创建新slice
newArray := make([]interface{}, newCapacity+1, newCapacity+1)
// 复制原slice到新slice,把队首变成0,队尾部变成原cap(l.data),将元素重新分布
for i := 0; i < l.size; i++ {
// 从原l.data的front位置开始遍历赋值给newArray
newArray[i] = l.data[(i+l.front)%cap(l.data)]
}
l.data = newArray
l.front = 0
//l.size就是原slice的最后一个index,l.tail等于原slice最后一个的index
l.tail = l.size
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/kklt1996/data-structure.git
git@gitee.com:kklt1996/data-structure.git
kklt1996
data-structure
data-structure
d7c879d1f31d

搜索帮助