バイナリツリーのルートを取得し、バイナリツリーのノードを反復処理するJavaイテレータ(つまり、メソッドnext
とメソッドが必要)を書くにはどうすればいいですか?hasNext
順番にファッション?
ベストアンサー1
サブツリーの最初の要素は常に左端の要素です。要素の次の要素は、その右サブツリーの最初の要素です。要素に右の子がない場合、次の要素は要素の最初の右の祖先です。要素に右の子も右の祖先もない場合、その要素は右端の要素であり、反復処理の最後になります。
私のコードが人間が読めるもので、あらゆるケースをカバーできることを願っています。
public class TreeIterator {
private Node next;
public TreeIterator(Node root) {
next = root;
if(next == null)
return;
while (next.left != null)
next = next.left;
}
public boolean hasNext(){
return next != null;
}
public Node next(){
if(!hasNext()) throw new NoSuchElementException();
Node r = next;
// If you can walk right, walk right, then fully left.
// otherwise, walk up until you come from left.
if(next.right != null) {
next = next.right;
while (next.left != null)
next = next.left;
return r;
}
while(true) {
if(next.parent == null) {
next = null;
return r;
}
if(next.parent.left == next) {
next = next.parent;
return r;
}
next = next.parent;
}
}
}
次のツリーを考えてみましょう。
d
/ \
b f
/ \ / \
a c e g
- 最初の要素は「ルートから完全に左」です
a
右の子がないので、次の要素は「左から来るまで上」になります。b
には右の子があるので、b
右のサブツリーを反復処理するc
には正しい子がありません。その親は ですがb
、これは走査済みです。次の親は ですがd
、これは走査されていないため、ここで停止します。d
には右サブツリーがあります。その左端の要素は ですe
。- ...
g
には右サブツリーがないので、上に進みます。f
右から来たので、は訪問済みですd
。は訪問済みです。d
親がないので、それ以上上に移動できません。右端のノードから来たので、反復処理は終了です。