PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/Search/Lucene/PriorityQueue.php

https://bitbucket.org/bigstylee/zend-framework
PHP | 171 lines | 56 code | 25 blank | 90 comment | 11 complexity | ae0b2f799808549cd142709153b99d68 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Search_Lucene
  17. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: PriorityQueue.php 24593 2012-01-05 20:35:02Z matthew $
  20. */
  21. /**
  22. * Abstract Priority Queue
  23. *
  24. * It implements a priority queue.
  25. * Please go to "Data Structures and Algorithms",
  26. * Aho, Hopcroft, and Ullman, Addison-Wesley, 1983 (corrected 1987 edition),
  27. * for implementation details.
  28. *
  29. * It provides O(log(N)) time of put/pop operations, where N is a size of queue
  30. *
  31. * @category Zend
  32. * @package Zend_Search_Lucene
  33. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  34. * @license http://framework.zend.com/license/new-bsd New BSD License
  35. */
  36. abstract class Zend_Search_Lucene_PriorityQueue
  37. {
  38. /**
  39. * Queue heap
  40. *
  41. * Heap contains balanced partial ordered binary tree represented in array
  42. * [0] - top of the tree
  43. * [1] - first child of [0]
  44. * [2] - second child of [0]
  45. * ...
  46. * [2*n + 1] - first child of [n]
  47. * [2*n + 2] - second child of [n]
  48. *
  49. * @var array
  50. */
  51. private $_heap = array();
  52. /**
  53. * Add element to the queue
  54. *
  55. * O(log(N)) time
  56. *
  57. * @param mixed $element
  58. */
  59. public function put($element)
  60. {
  61. $nodeId = count($this->_heap);
  62. $parentId = ($nodeId-1) >> 1; // floor( ($nodeId-1)/2 )
  63. while ($nodeId != 0 && $this->_less($element, $this->_heap[$parentId])) {
  64. // Move parent node down
  65. $this->_heap[$nodeId] = $this->_heap[$parentId];
  66. // Move pointer to the next level of tree
  67. $nodeId = $parentId;
  68. $parentId = ($nodeId-1) >> 1; // floor( ($nodeId-1)/2 )
  69. }
  70. // Put new node into the tree
  71. $this->_heap[$nodeId] = $element;
  72. }
  73. /**
  74. * Return least element of the queue
  75. *
  76. * Constant time
  77. *
  78. * @return mixed
  79. */
  80. public function top()
  81. {
  82. if (count($this->_heap) == 0) {
  83. return null;
  84. }
  85. return $this->_heap[0];
  86. }
  87. /**
  88. * Removes and return least element of the queue
  89. *
  90. * O(log(N)) time
  91. *
  92. * @return mixed
  93. */
  94. public function pop()
  95. {
  96. if (count($this->_heap) == 0) {
  97. return null;
  98. }
  99. $top = $this->_heap[0];
  100. $lastId = count($this->_heap) - 1;
  101. /**
  102. * Find appropriate position for last node
  103. */
  104. $nodeId = 0; // Start from a top
  105. $childId = 1; // First child
  106. // Choose smaller child
  107. if ($lastId > 2 && $this->_less($this->_heap[2], $this->_heap[1])) {
  108. $childId = 2;
  109. }
  110. while ($childId < $lastId &&
  111. $this->_less($this->_heap[$childId], $this->_heap[$lastId])
  112. ) {
  113. // Move child node up
  114. $this->_heap[$nodeId] = $this->_heap[$childId];
  115. $nodeId = $childId; // Go down
  116. $childId = ($nodeId << 1) + 1; // First child
  117. // Choose smaller child
  118. if (($childId+1) < $lastId &&
  119. $this->_less($this->_heap[$childId+1], $this->_heap[$childId])
  120. ) {
  121. $childId++;
  122. }
  123. }
  124. // Move last element to the new position
  125. $this->_heap[$nodeId] = $this->_heap[$lastId];
  126. unset($this->_heap[$lastId]);
  127. return $top;
  128. }
  129. /**
  130. * Clear queue
  131. */
  132. public function clear()
  133. {
  134. $this->_heap = array();
  135. }
  136. /**
  137. * Compare elements
  138. *
  139. * Returns true, if $el1 is less than $el2; else otherwise
  140. *
  141. * @param mixed $el1
  142. * @param mixed $el2
  143. * @return boolean
  144. */
  145. abstract protected function _less($el1, $el2);
  146. }