PriorityQueue.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:4k
源码类别:

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2004 The Apache Software Foundation
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. using System;
  17. namespace Lucene.Net.Util
  18. {
  19. /// <summary>A PriorityQueue maintains a partial ordering of its elements such that the
  20. /// least element can always be found in constant time.  Put()'s and pop()'s
  21. /// require log(size) time. 
  22. /// </summary>
  23. public abstract class PriorityQueue
  24. {
  25. private System.Object[] heap;
  26. private int size;
  27. private int maxSize;
  28. /// <summary>Determines the ordering of objects in this priority queue.  Subclasses
  29. /// must define this one method. 
  30. /// </summary>
  31. public abstract bool LessThan(System.Object a, System.Object b);
  32. /// <summary>Subclass constructors must call this. </summary>
  33. protected internal void  Initialize(int maxSize)
  34. {
  35. size = 0;
  36. int heapSize = maxSize + 1;
  37. heap = new System.Object[heapSize];
  38. this.maxSize = maxSize;
  39. }
  40. /// <summary> Adds an Object to a PriorityQueue in log(size) time.
  41. /// If one tries to add more objects than maxSize from initialize
  42. /// a RuntimeException (ArrayIndexOutOfBound) is thrown.
  43. /// </summary>
  44. public void  Put(System.Object element)
  45. {
  46. size++;
  47. heap[size] = element;
  48. UpHeap();
  49. }
  50. /// <summary> Adds element to the PriorityQueue in log(size) time if either
  51. /// the PriorityQueue is not full, or not lessThan(element, top()).
  52. /// </summary>
  53. /// <param name="element">
  54. /// </param>
  55. /// <returns> true if element is added, false otherwise.
  56. /// </returns>
  57. public virtual bool Insert(System.Object element)
  58. {
  59. if (size < maxSize)
  60. {
  61. Put(element);
  62. return true;
  63. }
  64. else if (size > 0 && !LessThan(element, Top()))
  65. {
  66. heap[1] = element;
  67. AdjustTop();
  68. return true;
  69. }
  70. else
  71. return false;
  72. }
  73. /// <summary>Returns the least element of the PriorityQueue in constant time. </summary>
  74. public System.Object Top()
  75. {
  76. if (size > 0)
  77. return heap[1];
  78. else
  79. return null;
  80. }
  81. /// <summary>Removes and returns the least element of the PriorityQueue in log(size)
  82. /// time. 
  83. /// </summary>
  84. public System.Object Pop()
  85. {
  86. if (size > 0)
  87. {
  88. System.Object result = heap[1]; // save first value
  89. heap[1] = heap[size]; // move last to first
  90. heap[size] = null; // permit GC of objects
  91. size--;
  92. DownHeap(); // adjust heap
  93. return result;
  94. }
  95. else
  96. return null;
  97. }
  98. /// <summary>Should be called when the Object at top changes values.  Still log(n)
  99. /// worst case, but it's at least twice as fast to <pre>
  100. /// { pq.top().change(); pq.adjustTop(); }
  101. /// </pre> instead of <pre>
  102. /// { o = pq.pop(); o.change(); pq.push(o); }
  103. /// </pre>
  104. /// </summary>
  105. public void  AdjustTop()
  106. {
  107. DownHeap();
  108. }
  109. /// <summary>Returns the number of elements currently stored in the PriorityQueue. </summary>
  110. public int Size()
  111. {
  112. return size;
  113. }
  114. /// <summary>Removes all entries from the PriorityQueue. </summary>
  115. public void  Clear()
  116. {
  117. for (int i = 0; i <= size; i++)
  118. heap[i] = null;
  119. size = 0;
  120. }
  121. private void  UpHeap()
  122. {
  123. int i = size;
  124. System.Object node = heap[i]; // save bottom node
  125. int j = SupportClass.Number.URShift(i, 1);
  126. while (j > 0 && LessThan(node, heap[j]))
  127. {
  128. heap[i] = heap[j]; // shift parents down
  129. i = j;
  130. j = SupportClass.Number.URShift(j, 1);
  131. }
  132. heap[i] = node; // install saved node
  133. }
  134. private void  DownHeap()
  135. {
  136. int i = 1;
  137. System.Object node = heap[i]; // save top node
  138. int j = i << 1; // find smaller child
  139. int k = j + 1;
  140. if (k <= size && LessThan(heap[k], heap[j]))
  141. {
  142. j = k;
  143. }
  144. while (j <= size && LessThan(heap[j], node))
  145. {
  146. heap[i] = heap[j]; // shift up child
  147. i = j;
  148. j = i << 1;
  149. k = j + 1;
  150. if (k <= size && LessThan(heap[k], heap[j]))
  151. {
  152. j = k;
  153. }
  154. }
  155. heap[i] = node; // install saved node
  156. }
  157. }
  158. }