迭代的树遍历
迭代扫描从树的最左端结点开始。从树根开始沿着左子节点链,直至定位一个具有空左子树的节点,该节点就是扫描的起始点。迭代器最初引用这个节点。根节点及其左子节点路径上所有中间节点都被压入堆栈。
树的迭代遍历基于下列一组规则:
- 在每个节点处,捕捉该节点的值。
- 如果这个节点的右分支不为空,那么就移动到该节点的右子节点,然后遍历左子节点路径直至定位一个具有空左子树的节点。遍历将所定位的节点标识为“下一个”节点。将对指定节点右子节点的引用与其左子节点路径上的所有中间节点都压入堆栈。
- 如果这个节点的右分支为空,那么就结束对该节点左分支、该节点本身以及该节点右分支的扫描。要访问的下一个节点位于堆栈中。如果堆栈不为空,那么就通过弹出操作来确定扫描中的下一个节点。如果堆栈为空,那么所有节点都已被访问,此时扫描结束。
-
1 public class InorderIterator
implements Iterator 2 { 3 private ALStack > s = null; 4 private TNode curr = null; 5 6 ... 7 } 8 private TNode goFarLeft(TNode t) 9 {10 if(t == null)11 return null;12 while(t.left != null)//最后一个节点不入栈13 {14 s.push(t);15 t = t.left;16 }17 return t;18 }19 public InorderIterator(TNode root)20 {21 s = new ALStack >();22 curr = goFarLeft(root);23 }24 public T next()25 {26 if(curr == null)27 throw new NoSuchElementException(28 "InorderScan: no elements remaining");29 T returnValue = curr.nodeValue;30 if(curr.right != null)31 curr = goFarLeft(curr.right);32 else if(!s.isEmpty())33 curr = (TNode )s.pop();34 return returnValue;35 }