//节点是对某种类型数据的封装;通过这种封装,能够对这种数据建立树形模型
//Node是Data的马甲,穿上马甲的Data能够组织成一棵树
public abstract class Node<T>
{
protected T _data;
public T Data
{
get
{
return _data;
}
set
{
_data = value;
}
}
}
//定义子节点集合。这样定义节点有一个好处,如果获得一个节点的引用,也就引用的以该节点为根的整棵树
public class CldNode<T> : Node<T>
{
public CldNode(T data)
{
_data = data;
}
public CldNode()
{ }
private List<CldNode<T>> _children;
public List<CldNode<T>> Children
{
get
{
if (_children == null) //从单例模式改的,不知道有没有问题?
{
lock (this)
{
if (_children == null)
{
_children = new List<CldNode<T>>();
}
}
}
return _children;
}
}
}
//后面使用堆栈模拟遍历树,这个辅助类定义了堆栈中的元素。//First表示堆栈中的节点,Second表示要遍历这个节点的第几个子
[Serializable]
public class Pair<FT, ST>
{
public Pair(FT first, ST second)
{
First = first;
Second = second;
}
public FT First
{
get;
set;
}
public ST Second
{
get;
set;
}
}
//不用递归是因为不知道用递归改怎么写成迭代器
public class CldNodeIterator<T>
{
private Stack<Pair<CldNode<T>, int>> _stack;
private CldNode<T> _root;
public CldNodeIterator(CldNode<T> root)
{
_root = root;
}
public CldNodeIterator() { }
public CldNode<T> Root
{
get
{
return _root;
}
set
{
_root = value;
}
}
//首先访问父节点
//然后访问所有的子结点
//上面这两点是递归的
public IEnumerable<T> FPermiseTraverse()
{
if (_stack == null)
{
_stack = new Stack<Pair<CldNode<T>, int>>(16);
}
_stack.Push(new Pair<CldNode<T>, int>(_root, -1));
while (_stack.Count != 0)
{
Pair<CldNode<T>, int> stkTop = _stack.Peek();
if (stkTop.Second == -1) //尚未开始遍历
{
yield return stkTop.First.Data;
stkTop.Second++;
continue;
}
if (stkTop.First.Children.Count == stkTop.Second) //已经结束
{
_stack.Pop();
if (_stack.Count != 0)
{
_stack.Peek().Second++;
}
continue;
}
_stack.Push(new Pair<CldNode<T>, int>(stkTop.First.Children[stkTop.Second], -1));
}
}
//先子后父
public IEnumerable<T> CPermiseTraverse()
{
if (_stack == null)
{
_stack = new Stack<Pair<CldNode<T>, int>>(16);
}
_stack.Push(new Pair<CldNode<T>, int>(_root, -1));
while (_stack.Count != 0)
{
Pair<CldNode<T>, int> stkTop = _stack.Peek();
if (stkTop.Second == -1) //尚未开始遍历
{
stkTop.Second++;
continue;
}
if (stkTop.First.Children.Count == stkTop.Second) //已经结束
{
yield return stkTop.First.Data;
_stack.Pop();
if (_stack.Count != 0)
{
_stack.Peek().Second++;
}
continue;
}
_stack.Push(new Pair<CldNode<T>, int>(stkTop.First.Children[stkTop.Second], -1));
}
}
}
//不知道有没有bug?我没仔细测。