- 插入新节点5
- 新节点5“上浮”到合适位置。
- 让原堆顶节点10出队
- 把最后一个节点1替换到堆顶位置。
- 节点1“下沉”,节点9成为新堆顶。
二叉堆节点“上浮”和“下沉”的时间复杂度都是O(logn),所以优先队列入队和出队的时间复杂度也是O(logn)!
完整实例优先队列类
Class PHA.YX.Arithmetic.PriorityQueue Extends %RegisteredObject
{
Property array As %ArrayOfDataTypes;
/// 上浮调整
Method upAdjustArray()
{
#dim childIndex as %Integer = ..array.Count() - 1
#dim parentIndex as %Integer = (childIndex - 1 ) \ 2 /* 这一定要取整数 */
/* temp保存插入的叶子节点值,用于最后的赋值 */
#dim temp as %Integer = ..array.GetAt(childIndex)
while((childIndex > 0)&&(temp > ..array.GetAt(parentIndex))){
/* 无需真正交换,单向赋值即可 */
d ..array.SetAt(..array.GetAt(parentIndex),childIndex)
s childIndex = parentIndex
s parentIndex = (parentIndex - 1) \ 2
}
d ..array.SetAt(temp,childIndex)
q ..array
}
/// 下沉调整
Method downAjustArray()
{
#dim parentIndex as %Integer = 0
#dim temp as %Integer = ..array.GetAt(parentIndex)
#dim childIndex as %Integer = 1
while(childIndex < ..array.Count()){
;w "childIndex i:"_childIndex _ " array.GetAt(childIndex + 1):" _array.GetAt(childIndex + 1)_ " array.GetAt(childIndex):" _array.GetAt(childIndex),!
/* 如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子 */
if (((childIndex + 1) < ..array.Count())&&(..array.GetAt(childIndex + 1) > ..array.GetAt(childIndex))){
s childIndex = childIndex + 1
}
;b:temp=1
;w "temp:"_temp _ " array.GetAt(childIndex):"_array.GetAt(childIndex),!
;w "childIndex:"_childIndex,!
;w array.GetAt(childIndex),!
/* 如果父节点小于任何一个孩子的值,直接跳出 */
if (temp >= ..array.GetAt(childIndex)){
quit /* 这一定是quit 而不是continue */
}
/* 无需真正交换,单向赋值即可 */
d ..array.SetAt(..array.GetAt(childIndex), parentIndex)
s parentIndex = childIndex
s childIndex = 2 * childIndex + 1
}
d ..array.SetAt(temp, parentIndex)
}
Method enQueue(key As %Integer)
{
d ..array.SetAt(key, ..array.Count())
d ..upAdjustArray()
}
Method deQueue()
{
i ..array.Count() <= 0 d
.throw ##class(PHA.COM.MOB.Exception).%New("数组已经为空!")
s head = ..array.GetAt(0)
d ..array.SetAt(..array.GetAt(..array.Count()),0)
d ..downAjustArray()
q head
}
Method %OnNew(array As %ArrayOfDataTypes) As %Status [ Private, ServerOnly = 1 ]
{
s ..array = ##class(%ArrayOfDataTypes).%New()
Quit $$$OK
}
}
调用
/// d ##class(PHA.YX.Arithmetic).PriorityQueue()
ClassMethod PriorityQueue()
{
#dim mPriorityQueue as PHA.YX.Arithmetic.PriorityQueue = ##class(PHA.YX.Arithmetic.PriorityQueue).%New()
d mPriorityQueue.enQueue(3)
d mPriorityQueue.enQueue(5)
d mPriorityQueue.enQueue(10)
d mPriorityQueue.enQueue(2)
d mPriorityQueue.enQueue(7)
w mPriorityQueue.deQueue(),!
w mPriorityQueue.deQueue(),!
w mPriorityQueue.deQueue(),!
w mPriorityQueue.deQueue(),!
w mPriorityQueue.deQueue(),!
w mPriorityQueue.deQueue(),!
}
DHC-APP>d ##class(PHA.YX.Arithmetic).PriorityQueue()
10
7
5
3
2