.NET 实现一个多分叉树形数据结构

由于项目上的某些原因,如果使用树形结构的话,将会大大减少一些逻辑上的工作,

项目中原来也是树形结构,但是及其恶心,每一层都要自己去定义父节点和子节点,

还好项目层级不多,如果多了的话,那还不'日天',所以自己花了点时间简单实现了一个树形结构,

有不足之处还望不吝赐教.

先定义树的基本信息:

/// <summary>
    /// 实现一个树形结构
    /// </summary>
    public class Tree<T>
    {
        public Tree()
        {
            Deep = 1;
        }

        public int Deep { get; set; }

        //当前节点名字
        public string Name { get; set; }
        //当前节点值
        public T Value { get; set; }

        //父节点
        public Tree<T> Perent { get; set; }

        //子节点
        private List<Tree<T>> Child = new List<Tree<T>>();
}

一个树形结构需要有父节点和子节点,还需要节点中存储的内容,这里,我还给节点取了个名字

接下来需要实现树形结构的一些操作方法,这里就全部贴出来,下面的内容只是对上面tree的补充:

        //增加子节点
        public void AddChild(Tree<T> tree)
        {
            if (GetByName(tree.Name) != null)
            {
                return;
            }
            tree.Perent = this;
            tree.Deep = Deep + 1;
            Child.Add(tree);
        }
        //移除子节点,子节点以后的节点全部没有了
        public void RemoveChild()
        {
            Child.Clear();
        }

        #region AllTree

        //根据名字去寻找节点
        public Tree<T> GetByName(string name)
        {
            Tree<T> root = GetRootTree(this);
            List<Tree<T>> list = GatAll(root);
            var result = list.Where(c => c.Name == name).ToList();
            if (result.Count <= 0)
            {
                return null;
            }
            else
            {
                return result[0];
            }
        }
        //根据树根获得所有节点
        public List<Tree<T>> GatAll(Tree<T> tree)
        {
            List<Tree<T>> list = new List<Tree<T>>();
            list.Add(tree);
            if (tree.Child == null)
            {
                return null;
            }
            list.AddRange(tree.Child);
            foreach (var tree1 in tree.Child)
            {
                list.AddRange(GatAll(tree1));
            }
            return list.Distinct().ToList();
        }

        //获得树根节点
        public Tree<T> GetRootTree(Tree<T> tree)
        {
            if (tree.Perent == null)
            {
                return tree;
            }
            return GetRootTree(tree.Perent);
        }

        //获得树的深度
        public int GetDeep(Tree<T> tree)
        {
            List<Tree<T>> list = GetDeepTree(tree);
            return list.Max(c => c.Deep);
        }

        // 根据根节点获取所有最终节点
        public List<Tree<T>> GetDeepTree(Tree<T> tree)
        {
            List<Tree<T>> list = new List<Tree<T>>();
            if (tree.Child.Count <= 0)
            {
                list.Add(tree);
            }
            else
            {
                foreach (var tree1 in tree.Child)
                {
                    if (tree1.Child.Count <= 0)
                    {
                        list.Add(tree1);
                    }
                    else
                    {
                        foreach (var tree2 in tree1.Child)
                        {
                            list.AddRange(GetDeepTree(tree2));
                        }
                    }
                }
            }
            return list;
        }

        #endregion

 我的单元单元测试如下:

  Tree.Tree<string> treeRoot = new Tree.Tree<string>() { Name = "Device" };
            Tree.Tree<string> treeRoot1 = new Tree.Tree<string>() { Name = "Chanel1" };
            Tree.Tree<string> treeRoot2 = new Tree.Tree<string>() { Name = "Chanel2" };
            Tree.Tree<string> treeRoot3 = new Tree.Tree<string>() { Name = "Chanel3" };
            treeRoot.AddChild(treeRoot1);
            treeRoot.AddChild(treeRoot2);
            treeRoot.AddChild(treeRoot3);
            Tree.Tree<string> final = new Tree.Tree<string>() { Name = "final" };
            treeRoot3.AddChild(final);

            string value = treeRoot.GetRootTree(final).Name;
            Assert.AreEqual(treeRoot.Name, value);

            List<Tree.Tree<string>> list = treeRoot.GatAll(treeRoot);
            Assert.IsTrue(list.Count == 5);

            List<Tree.Tree<string>> result = treeRoot.GetDeepTree(treeRoot);
            Assert.AreEqual(3, result.Count);

            Tree.Tree<string> tree = treeRoot.GetByName("Chanel2");
            Assert.AreEqual("Device",tree.Perent.Name);

            Assert.AreEqual(3, treeRoot.GetDeep(treeRoot));

            treeRoot.RemoveChild();
            Assert.AreEqual(1, treeRoot.GetDeep(treeRoot));

 

posted @ 2018-01-11 14:40  MT老绵羊  阅读(1292)  评论(0)    收藏  举报