文章目录

第十一章 Caché 算法与数据结构 优先队列
插入
  • 插入新节点5

第十一章 Caché 算法与数据结构 优先队列_Caché

  • 新节点5“上浮”到合适位置。

第十一章 Caché 算法与数据结构 优先队列_算法_02

出队
  • 让原堆顶节点10出队

第十一章 Caché 算法与数据结构 优先队列_队列_03

  • 把最后一个节点1替换到堆顶位置。

第十一章 Caché 算法与数据结构 优先队列_Caché_04

  • 节点1“下沉”,节点9成为新堆顶。

第十一章 Caché 算法与数据结构 优先队列_队列_05

时间复杂度

二叉堆节点“上浮”和“下沉”的时间复杂度都是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