双端队列是指允许两端都可以进行入队和出队操作的队列,其元素的逻辑结构仍是线性结构。将队列的两端分别称为前端和后端,两端都可以入队和出队。
Class PHA.YX.Arithmetic.DoubleQueue.Node Extends %RegisteredObject
{
/* 数据节点 */
Property data;
/* 头节点 */
Property front As Node;
/* 尾节点 */
Property next As Node;
Method %OnNew(data, front As Node, next As Node) As %Status [ Private, ServerOnly = 1 ]
{
s $this.data = data
s $this.front = front
s $this.next = next
Quit $$$OK
}
Method getData()
{
q ..data
}
Method setData(data)
{
s $this.data = data
}
Method getFront()
{
q ..front
}
Method setFront(front As Node)
{
s $this.front = front
}
Method getNext()
{
q ..next
}
Method setNext(next As Node)
{
s $this.next = next
}
}
Class PHA.YX.Arithmetic.DoubleQueue Extends %RegisteredObject
{
/* 队列长度 */
Property size As %Integer [ InitialExpression = 0 ];
/* 队首 */
Property head As PHA.YX.Arithmetic.DoubleQueue.Node;
/* 队尾 */
Property tail As PHA.YX.Arithmetic.DoubleQueue.Node;
/* 队头增加元素 */
Method addHead(data)
{
s node = ##class(PHA.YX.Arithmetic.DoubleQueue.Node).%New(data, "", ..head)
i ..isEmpty() d
.s ..tail = node
e d
.d ..head.setFront(node)
s ..head = node
s ..size = ..size + 1
}
/* 移除头元素 */
Method removeHead()
{
s target = ""
i '..isEmpty() d
.s target = ..head.getData()
.s ..head = ..head.getNext()
.i ..head = "" d
..s ..tail = ""
s ..size = ..size - 1
q target
}
/* 队尾增加元素 */
Method addLast(data)
{
s node = ##class(PHA.YX.Arithmetic.DoubleQueue.Node).%New(data, ..tail, "")
i ..isEmpty() d
.s ..tail = node
e d
.d ..tail.setNext(node)
.s ..tail = node
s ..size = ..size + 1
}
/* 移除队尾元素 */
Method removeLast()
{
s target = ""
i '..isEmpty() d
.s target = ..tail.getData()
.s ..tail = ..tail.getFront()
.i ..tail = "" d
..s ..head = ""
.s ..size = ..size - 1
q target
}
/* 判断队列是否为空 */
Method isEmpty()
{
q $s(..size = 0 : $$$YES, 1 : $$$NO)
}
/* 队列长度 */
Method size()
{
q ..size
}
/* 清除队列 */
Method clear()
{
s ..head = ""
s ..tail = ""
s ..size = 0
}
/* 队首循环遍历队列 */
Method foreachHead()
{
i ..isEmpty() d
.throw ##class(PHA.COM.MOB.Exception).%New("当前队列为空!")
e d
.f i = ..size : -1 : 1 d
..w ..head.getData(),!
..d ..addLast(..removeHead())
w "======队列正序遍历完成======",!
}
/* 队尾循环遍历队列 */
Method foreachLast()
{
i ..isEmpty() d
.throw ##class(PHA.COM.MOB.Exception).%New("当前队列为空!")
e d
.f i = ..size : -1 : 1 d
..w ..tail.getData(),!
..d ..addHead(..removeLast())
w "======队列倒序遍历完成======",!
}
}
/// w ##class(PHA.YX.Arithmetic).DoubleQueue()
ClassMethod DoubleQueue()
{
s $zt = "ErrCircularQueue"
#dim doubleQueue as PHA.YX.Arithmetic.DoubleQueue = ##class(PHA.YX.Arithmetic.DoubleQueue).%New()
d doubleQueue.addHead(1)
d doubleQueue.addHead(2)
d doubleQueue.addLast(3)
d doubleQueue.addLast(4)
w doubleQueue.size(),!
w "======队列长度======",!
d doubleQueue.foreachLast()
d doubleQueue.foreachHead()
d doubleQueue.removeHead()
d doubleQueue.removeLast()
w doubleQueue.size(),!
w "======队列长度======",!
d doubleQueue.foreachLast()
d doubleQueue.foreachHead()
q ""
ErrCircularQueue
q $ze
}
DHC-APP>w ##class(PHA.YX.Arithmetic).DoubleQueue()
4
======队列长度======
4
3
1
2
======队列倒序遍历完成======
2
1
3
4
======队列正序遍历完成======
2
======队列长度======
3
1
======队列倒序遍历完成======
1
3
======队列正序遍历完成======