迭代器访问树
2008-03-26 21:47
267 查看
//节点是对某种类型数据的封装;通过这种封装,能够对这种数据建立树形模型
//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?我没仔细测。
//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?我没仔细测。
相关文章推荐
- Google Mapplets
- [PSTZine_0x01]
- 该怎麽用 new 来分配多维阵列?
- Asp.NET ??運算符
- GridView与DropDownList如何很好地结合
- 裁员不代表集成电路进入冬天
- 罗斯柴尔德盾徽下的德国和意大利
- 多表头导出Excel
- 经典歌曲:30 minutes
- 正确实现 IDisposable 接口
- tcl/tk参考——控制结构error
- 去清华捐完钱后感
- linux 中安装myEclipse6.0.1
- 于GridView的数据格式化显示
- 几种典型算法的快速比较函数
- 点石互动--石头之:怎样判断站点收录状况合理(系列三)
- 本人所用的C++开发环境
- 是择业还是考研?
- Java Persistence with Hibernate中文版Hibernate实战第2版出版
- 使用 MySQL Date/Time 类型