PHP で AVL ツリー (自己均衡二分探索ツリー) を実装しており、かなり正常に動作しています。インオーダー、プリオーダー、およびレベルオーダーのイテレーターが機能していますが、BST のポストオーダー イテレーターを実行する方法がわかりません。Google 検索では、反復的なポストオーダー トラバーサルを行う方法が見つかりますが、イテレータは見つかりません。
これまでのところ、私の唯一の成功は、配列を構築し、配列イテレータを返すためにポストオーダー トラバーサルを使用することでした。これは、ツリーを 2 回反復し、スペースの複雑さが増すため、良くありません。
ポストオーダーイテレータを構築するための一般的なアルゴリズムは何ですか?
phpタグがここにある唯一の理由は、PHP の反復子が Java や C++ の反復子と異なるためです。あなたのアドバイスに影響するかもしれません。
また、PHP にジェネレーターがあれば、ポストオーダー トラバーサルは単純に値を生成し、それを iterator に変換できるため、これは簡単です。. .
編集:これは順序イテレータの実装です。ポストオーダーイテレータに私が何を求めているかを理解するのに役立つかもしれません:
class InOrderIterator implements Iterator {
/**
* @var ArrayStack
*/
protected $stack;
/**
* @var BinaryNode
*/
protected $root;
/**
* @var BinaryNode
*/
protected $value;
public function __construct(BinaryNode $root) {
$this->stack = new ArrayStack;
$this->root = $root;
}
/**
* @link http://php.net/manual/en/iterator.current.php
* @return mixed
*/
public function current() {
return $this->value->getValue();
}
/**
* @link http://php.net/manual/en/iterator.next.php
* @return void
*/
public function next() {
/**
* @var BinaryNode $node
*/
$node = $this->stack->pop();
$right = $node->getRight();
if ($right !== NULL) {
// left-most branch of the right side
for ($left = $right; $left !== NULL; $left = $left->getLeft()) {
$this->stack->push($left);
}
}
if ($this->stack->isEmpty()) {
$this->value = NULL;
return;
}
$this->value = $this->stack->peek();
}
/**
* @link http://php.net/manual/en/iterator.key.php
* @return NULL
*/
public function key() {
return NULL; //no keys in a tree . . .
}
/**
* @link http://php.net/manual/en/iterator.valid.php
* @return boolean
*/
public function valid() {
return $this->value !== NULL;
}
/**
* @link http://php.net/manual/en/iterator.rewind.php
* @return void
*/
public function rewind() {
$this->stack->clear();
for ($current = $this->root; $current !== NULL; $current = $current->getLeft()) {
$this->stack->push($current);
}
$this->value = $this->stack->peek();
}
}