用迭代器实现二叉树的中序遍历

简单定义一个抽象的节点类,为了看上去更通用一点,写成了比较难看的泛型:

 1  public  abstract  class TreeNode<TNode, TValue>
 2      where TNode : TreeNode<TNode, TValue>,  new()
 3 {
 4      public TValue Value {  getset; }
 5 
 6      public TNode LeftChild {  getprotected  set; }
 7 
 8      public TNode RightChild {  getprotected  set; }
 9 
10      public  abstract TNode CreateLeftChild(TValue value);
11 
12      public  abstract TNode CreateRightChild(TValue value);
13 }

 

然后我们的二叉树单独写一个接口,里面放一个根节点,然后继承一下IEnumerable,表示我们是可以被迭代的:

 1  public  interface IBinaryTree< out TNode> : IEnumerable<TNode>
 2 {
 3     TNode Root {  get; }
 4 }
 5 
 6  public  class BinaryTree<TNode, TValue> : IBinaryTree<TNode>
 7      where TNode : TreeNode<TNode, TValue>,  new()
 8 {
 9      public TNode Root {  getprotected  set; }
10 
11      public BinaryTree(TValue value)
12     {
13         Root =  new TNode { Value = value };
14     }
15 
16      #region IEnumerable
17 
18      public IEnumerator<TNode> GetEnumerator()
19     {
20          return  new InorderTraversalBinaryTreeEnumerator<TNode, TValue>(Root);
21     }
22 
23     IEnumerator IEnumerable.GetEnumerator()
24     {
25          return GetEnumerator();
26     }
27 
28      #endregion
29 }

 

 GetEnumerator方法里那个长长的我胡乱命名的东西,就是所谓的迭代器了。用一个栈来配合迭代当前访问的节点:

 1  public  class InorderTraversalBinaryTreeEnumerator<TNode, TValue> : IEnumerator<TNode>
 2      where TNode : TreeNode<TNode, TValue>,  new()
 3 {
 4      private  readonly Stack<TNode> _stack =  new Stack<TNode>();
 5      private TNode _current;
 6 
 7     TNode IEnumerator<TNode>.Current
 8     {
 9          get {  return _current; }
10     }
11 
12      object IEnumerator.Current
13     {
14          get {  return _current; }
15     }
16 
17      public InorderTraversalBinaryTreeEnumerator(TNode root)
18     {
19         FindLeftBottomNode(root);
20     }
21 
22      bool IEnumerator.MoveNext()
23     {
24          if (_stack.Count ==  0)
25              return  false;
26 
27         _current = _stack.Pop();
28 
29         FindLeftBottomNode(_current.RightChild);
30 
31          return  true;
32     }
33 
34      private  void FindLeftBottomNode(TNode node)
35     {
36          while (node !=  null)
37         {
38             _stack.Push(node);
39             node = node.LeftChild;
40         }
41     }
42 
43      void IEnumerator.Reset()
44     {
45     }
46 
47      void IDisposable.Dispose()
48     {
49     }
50 }

 

基础代码就这些,下面演示一个可以在控制器打印出来的二叉树。

为了打印方便,给节点扩展了Parent属性,外加一点简单的判断方法:

 1  public  class PrintableTreeNode : TreeNode<PrintableTreeNode,  int>
 2 {
 3      public PrintableTreeNode Parent {  getprivate  set; }
 4 
 5      public PrintableTreeNode()
 6         :  this( null)
 7     {
 8     }
 9 
10      public PrintableTreeNode(PrintableTreeNode parent)
11     {
12         Parent = parent;
13     }
14 
15      public  override PrintableTreeNode CreateLeftChild( int value)
16     {
17          return LeftChild =  new PrintableTreeNode { Value = value, Parent =  this };
18     }
19 
20      public  override PrintableTreeNode CreateRightChild( int value)
21     {
22          return RightChild =  new PrintableTreeNode { Value = value, Parent =  this };
23     }
24 
25      public  bool IsLeftChild()
26     {
27          return Parent !=  null && ReferenceEquals( this, Parent.LeftChild);
28     }
29 
30      public  bool IsRightChild()
31     {
32          return Parent !=  null && ReferenceEquals( this, Parent.RightChild);
33     }
34 }
35 
36  public  interface IPrintableBinaryTree : IBinaryTree<PrintableTreeNode>
37 {
38      void Print();
39 }

 

 Print的实现就不贴出来了。

 随机生成一棵树,然后直接foreach就能中序遍历整棵树了:

 

 

转载于:https://www.cnblogs.com/LeoZ/p/4485036.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值