活到老学到老

现学现卖

博客园 首页 新随笔 联系 订阅 管理

//节点是对某种类型数据的封装;通过这种封装,能够对这种数据建立树形模型
//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?我没仔细测。

posted on 2008-03-26 21:47  John Rambo  阅读(462)  评论(1编辑  收藏  举报