Permalink
Browse files

Many changes, mostly iterator-centric.

  • Loading branch information...
1 parent b1331ad commit b24101c421a17b9127b59ca14eae269bd28b3b6e @morrisonlevi committed Nov 14, 2012
View
@@ -2,10 +2,10 @@
namespace Spl;
-use Iterator;
+use IteratorAggregate;
-class ArrayStack implements Iterator, Stack {
+class ArrayStack implements IteratorAggregate, Stack {
private $stack = array();
@@ -77,48 +77,8 @@ public function peekBack() {
return $this->stack[count($this->stack) - 1];
}
- /**
- * @link http://php.net/manual/en/iterator.current.php
- * @return mixed
- */
- public function current() {
- return current($this->stack);
- }
-
- /**
- * @link http://php.net/manual/en/iterator.next.php
- * @return void
- */
- public function next() {
- prev($this->stack);
- }
-
- /**
- * @link http://php.net/manual/en/iterator.key.php
- * @return mixed
- */
- public function key() {
- $count = count($this->stack);
- if ($count === 0) {
- return NULL;
- }
- return count($this->stack) - key($this->stack) - 1;
- }
-
- /**
- * @link http://php.net/manual/en/iterator.valid.php
- * @return boolean
- */
- public function valid() {
- return key($this->stack) !== NULL;
- }
-
- /**
- * @link http://php.net/manual/en/iterator.rewind.php
- * @return void
- */
- public function rewind() {
- end($this->stack);
+ function getIterator() {
+ return new ArrayStackIterator($this->stack);
}
}
@@ -0,0 +1,64 @@
+<?php
+
+namespace Spl;
+
+class ArrayStackIterator implements StackIterator {
+
+ /**
+ * @var array
+ */
+ private $stack;
+
+ function __construct(array $stack) {
+ $this->stack = $stack;
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.current.php
+ * @return mixed
+ */
+ public function current() {
+ return current($this->stack);
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.next.php
+ * @return void
+ */
+ public function next() {
+ prev($this->stack);
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.key.php
+ * @return mixed
+ */
+ public function key() {
+ $count = count($this->stack);
+ if ($count === 0) {
+ return NULL;
+ }
+ return count($this->stack) - key($this->stack) - 1;
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.valid.php
+ * @return boolean
+ */
+ public function valid() {
+ return key($this->stack) !== NULL;
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.rewind.php
+ * @return void
+ */
+ public function rewind() {
+ end($this->stack);
+ }
+
+ function count() {
+ return count($this->stack);
+ }
+
+}
@@ -2,8 +2,7 @@
namespace Spl;
-use IteratorAggregate,
- Traversable;
+use IteratorAggregate;
class BinarySearchTree implements IteratorAggregate, Collection {
@@ -46,6 +45,7 @@ function __construct($comparator = NULL) {
*/
function add($element) {
$this->root = $this->addNode($element, $this->root);
+ $this->cache = NULL;
}
/**
@@ -60,7 +60,6 @@ protected function addNode($element, BinaryTree $node = NULL) {
return new BinaryTree($element);
}
-
$comparisonResult = call_user_func($this->comparator, $element, $node->getValue());
if ($comparisonResult < 0) {
@@ -79,6 +78,7 @@ protected function addNode($element, BinaryTree $node = NULL) {
*/
function remove($element) {
$this->root = $this->removeNode($element, $this->root);
+ $this->cache = NULL;
}
/**
@@ -220,28 +220,39 @@ function isEmpty() {
}
/**
+ * @var BinaryTree
+ */
+ private $cache = NULL;
+
+ /**
* @param int $order [optional]
*
* @return BinaryTreeIterator
*/
function getIterator($order = self::TRAVERSE_IN_ORDER) {
$iterator = NULL;
+
+ $root = $this->cache ?: (
+ $this->root !== NULL
+ ? clone $this->root
+ : NULL
+ );
switch ($order) {
case self::TRAVERSE_LEVEL_ORDER:
- $iterator = new LevelOrderIterator($this->root);
+ $iterator = new LevelOrderIterator($root);
break;
case self::TRAVERSE_PRE_ORDER:
- $iterator = new PreOrderIterator($this->root);
+ $iterator = new PreOrderIterator($root);
break;
case self::TRAVERSE_POST_ORDER:
- $iterator = new PostOrderIterator($this->root);
+ $iterator = new PostOrderIterator($root);
break;
case self::TRAVERSE_IN_ORDER:
default:
- $iterator = new InOrderIterator($this->root);
+ $iterator = new InOrderIterator($root);
}
return $iterator;
@@ -274,4 +285,13 @@ function count() {
return $this->size;
}
+ function __clone() {
+ $tree = new BinarySearchTree();
+ $tree->size = $this->size;
+ $tree->root = $this->root === NULL
+ ? NULL
+ : clone $this->root;
+
+ return $tree;
+ }
}
View
@@ -127,4 +127,17 @@ function getInOrderPredecessor() {
}
+ function __clone() {
+ $tree = new BinaryTree($this->value);
+ $tree->left = $this->left === NULL
+ ? NULL
+ : clone $this->left;
+
+ $tree->right = $this->right === NULL
+ ? NULL
+ : clone $this->right;
+
+ return $tree;
+ }
+
}
@@ -0,0 +1,10 @@
+<?php
+
+namespace Spl;
+
+use Countable,
+ Iterator;
+
+interface CountableIterator extends Countable, Iterator {
+
+}
@@ -0,0 +1,7 @@
+<?php
+
+namespace Spl;
+
+interface CountableSeekableIterator extends CountableIterator, \SeekableIterator {
+
+}
View
@@ -165,14 +165,10 @@ public function count() {
}
/**
- * (PHP 5 &gt;= 5.0.0)<br/>
- * Retrieve an external iterator
- *
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
- * @return Traversable An instance of an object implementing <b>Iterator</b> or
- * <b>Traversable</b>
+ * @return SortedMapIterator
*/
public function getIterator() {
- return new SortedMapIterator($this->avl->getIterator());
+ return new SortedMapIterator($this->avl->getIterator(), $this->avl->count());
}
}
@@ -2,17 +2,22 @@
namespace Spl;
-use Iterator;
-
-class SortedMapIterator implements Iterator {
+class SortedMapIterator implements CountableIterator {
/**
* @var BinaryTreeIterator
*/
private $iterator;
- public function __construct(BinaryTreeIterator $iterator) {
+ private $size;
+
+ public function __construct(BinaryTreeIterator $iterator, $size) {
$this->iterator = $iterator;
+ $this->size = $size;
+ }
+
+ public function count() {
+ return $this->size;
}
/**
View
@@ -8,7 +8,7 @@
class SortedSet implements IteratorAggregate, Set {
/**
- * @var BinarySearchTree
+ * @var AvlTree
*/
private $bst;
@@ -101,7 +101,7 @@ function removeAll(Traversable $items) {
* @return Traversable
*/
public function getIterator() {
- return $this->bst->getIterator();
+ return new SortedSetIterator($this->bst->getIterator(), $this->count());
}
}
@@ -0,0 +1,67 @@
+<?php
+
+namespace Spl;
+
+class SortedSetIterator implements CountableIterator {
+
+ private $key = 0;
+
+ public function __construct(BinaryTreeIterator $iterator, $size) {
+ $this->iterator = $iterator;
+ $this->size = $size;
+ $this->iterator->rewind();
+ }
+
+ /**
+ * @link http://php.net/manual/en/countable.count.php
+ * @return int
+ */
+ public function count() {
+ return $this->size;
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.current.php
+ * @return mixed
+ */
+ public function current() {
+ return $this->iterator->current();
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.next.php
+ * @return void
+ */
+ public function next() {
+ $this->iterator->next();
+ $this->key++;
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.key.php
+ * @return mixed
+ */
+ public function key() {
+ return $this->size > 0
+ ? $this->key
+ : NULL;
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.valid.php
+ * @return boolean
+ */
+ public function valid() {
+ return $this->iterator->valid();
+ }
+
+ /**
+ * @link http://php.net/manual/en/iterator.rewind.php
+ * @return void
+ */
+ public function rewind() {
+ $this->iterator->rewind();
+ $this->key = 0;
+ }
+
+}
@@ -0,0 +1,7 @@
+<?php
+
+namespace Spl;
+
+interface StackIterator extends CountableIterator {
+
+}
Oops, something went wrong.

0 comments on commit b24101c

Please sign in to comment.