273 lines
7.7 KiB
Go

package deque
//@Title deque
//@Description
// deque双队列容器包
// 区别于queue的动态数组实现方式,deque采取将数组和链表相结合的方案
// 该容器既可以在首部增删元素,也可以在尾部增删元素
// deque在扩容和缩容时,都是固定增加2^10的空间,同时这一部分空间形成链表节点,并串成链表去保存
// 可接纳不同类型的元素
// 通过并发控制锁保证了在高并发过程中的数据一致性
import (
"github.com/hlccd/goSTL/utils/iterator"
"sync"
)
//deque双向队列结构体
//包含链表的头尾节点指针
//当删除节点时通过头尾节点指针进入链表进行删除
//当一个节点全部被删除后则释放该节点,同时首尾节点做相应调整
//当添加节点时若未占满节点空间时移动下标并做覆盖即可
//当添加节点时空间已使用完毕时,根据添加位置新建一个新节点补充上去
type Deque struct {
first *node //链表首节点指针
last *node //链表尾节点指针
size uint64 //当前存储的元素个数
mutex sync.Mutex //并发控制锁
}
//deque双向队列容器接口
//存放了deque容器可使用的函数
//对应函数介绍见下方
type dequer interface {
Iterator() (i *Iterator.Iterator) //返回包含双向队列中所有元素的迭代器
Size() (size uint64) //返回该双向队列中元素的使用空间大小
Clear() //清空该双向队列
Empty() (b bool) //判断该双向队列是否为空
PushFront(e interface{}) //将元素e添加到该双向队列的首部
PushBack(e interface{}) //将元素e添加到该双向队列的尾部
PopFront() (e interface{}) //将该双向队列首元素弹出
PopBack() (e interface{}) //将该双向队列首元素弹出
Front() (e interface{}) //获取该双向队列首部元素
Back() (e interface{}) //获取该双向队列尾部元素
}
//@title New
//@description
// 新建一个deque双向队列容器并返回
// 初始deque双向队列的链表首尾节点为nil
// 初始size为0
//@receiver nil
//@param nil
//@return d *Deque 新建的deque指针
func New() *Deque {
return &Deque{
first: nil,
last: nil,
size: 0,
mutex: sync.Mutex{},
}
}
//@title Iterator
//@description
// 以deque双向队列容器做接收者
// 将deque双向队列容器中所承载的元素放入迭代器中
// 节点的冗余空间不释放
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return i *iterator.Iterator 新建的Iterator迭代器指针
func (d *Deque) Iterator() (i *Iterator.Iterator) {
if d == nil {
d = New()
}
tmp := make([]interface{}, 0, d.size)
//遍历链表的所有节点,将其中承载的元素全部复制出来
for m := d.first; m != nil; m = m.nextNode() {
tmp = append(tmp, m.value()...)
}
return Iterator.New(&tmp)
}
//@title Size
//@description
// 以deque双向队列容器做接收者
// 返回该容器当前含有元素的数量
// 该长度并非实际占用空间数量
// 若容器为空则返回0
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return size uint64 容器中实际使用元素所占空间大小
func (d *Deque) Size() (size uint64) {
if d == nil {
d = New()
}
return d.size
}
//@title Clear
//@description
// 以deque双向队列容器做接收者
// 将该容器中所承载的元素清空
// 将该容器的首尾指针均置nil,将size重置为0
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return nil
func (d *Deque) Clear() {
if d == nil {
d = New()
return
}
d.mutex.Lock()
d.first = nil
d.last = nil
d.size = 0
d.mutex.Unlock()
}
//@title Empty
//@description
// 以deque双向队列容器做接收者
// 判断该deque双向队列容器是否含有元素
// 如果含有元素则不为空,返回false
// 如果不含有元素则说明为空,返回true
// 如果容器不存在,返回true
// 该判断过程通过size进行判断,为0则为true,否则为false
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return b bool 该容器是空的吗?
func (d *Deque) Empty() (b bool) {
if d == nil {
d = New()
}
return d.Size() == 0
}
//@title PushFront
//@description
// 以deque双向队列向量容器做接收者
// 在容器首部插入元素
// 通过链表首节点进行添加
//@receiver d *Deque 接收者的deque指针
//@param e interface{} 待插入元素
//@return nil
func (d *Deque) PushFront(e interface{}) {
if d == nil {
d = New()
}
d.mutex.Lock()
d.size++
//通过首节点进行添加
if d.first == nil {
d.first = createFirst()
d.last = d.first
}
d.first = d.first.pushFront(e)
d.mutex.Unlock()
}
//@title PushBack
//@description
// 以deque双向队列向量容器做接收者
// 在容器尾部插入元素
// 通过链表尾节点进行添加
//@receiver d *Deque 接收者的deque指针
//@param e interface{} 待插入元素
//@return nil
func (d *Deque) PushBack(e interface{}) {
if d == nil {
d = New()
}
d.mutex.Lock()
d.size++
//通过尾节点进行添加
if d.last == nil {
d.last = createLast()
d.first = d.last
}
d.last = d.last.pushBack(e)
d.mutex.Unlock()
}
//@title PopFront
//@description
// 以deque双向队列容器做接收者
// 利用首节点进行弹出元素,可能存在首节点全部释放要进行首节点后移的情况
// 当元素全部删除后,释放全部空间,将首尾节点都设为nil
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return e interface{} 首元素
func (d *Deque) PopFront() (e interface{}) {
if d == nil {
d = New()
}
if d.size == 0 {
return nil
}
d.mutex.Lock()
//利用首节点删除首元素
//返回新的首节点
e = d.first.front()
d.first = d.first.popFront()
d.size--
if d.size == 0 {
//全部删除完成,释放空间,并将首尾节点设为nil
d.first = nil
d.last = nil
}
d.mutex.Unlock()
return e
}
//@title PopBack
//@description
// 以deque双向队列容器做接收者
// 利用尾节点进行弹出元素,可能存在尾节点全部释放要进行尾节点前移的情况
// 当元素全部删除后,释放全部空间,将首尾节点都设为nil
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return e interface{} 尾元素
func (d *Deque) PopBack() (e interface{}) {
if d == nil {
d = New()
}
if d.size == 0 {
return nil
}
d.mutex.Lock()
//利用尾节点删除首元素
//返回新的尾节点
d.last = d.last.popBack()
e = d.last.back()
d.size--
if d.size == 0 {
//全部删除完成,释放空间,并将首尾节点设为nil
d.first = nil
d.last = nil
}
d.mutex.Unlock()
return e
}
//@title Front
//@description
// 以deque双向队列容器做接收者
// 返回该容器的第一个元素,利用首节点进行寻找
// 若该容器当前为空,则返回nil
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return e interface{} 容器的第一个元素
func (d *Deque) Front() (e interface{}) {
if d == nil {
d = New()
}
return d.first.front()
}
//@title Back
//@description
// 以deque双向队列容器做接收者
// 返回该容器的最后一个元素,利用尾节点进行寻找
// 若该容器当前为空,则返回nil
//@receiver d *Deque 接收者的deque指针
//@param nil
//@return e interface{} 容器的最后一个元素
func (d *Deque) Back() (e interface{}) {
if d == nil {
d = New()
}
return d.last.back()
}