Build a simple, high performance Tree Data Structure in c#

后端 未结 3 431
不知归路
不知归路 2020-12-04 08:56

I need to create a product catalog, in tree type.

every tree node presents by a ID(string), the functions on the tree data only 2:

  1. getChild(strin
相关标签:
3条回答
  • 2020-12-04 09:09

    Just make a class out of it.

    UPDATED:

    class TreeNode : IEnumerable<TreeNode>
    {
        private readonly Dictionary<string, TreeNode> _children =
                                            new Dictionary<string, TreeNode>();
    
        public readonly string ID;
        public TreeNode Parent { get; private set; }
    
        public TreeNode(string id)
        {
            this.ID = id;
        }
    
        public TreeNode GetChild(string id)
        {
            return this._children[id];
        }
    
        public void Add(TreeNode item)
        {
            if (item.Parent != null)
            {
                item.Parent._children.Remove(item.ID);
            }
    
            item.Parent = this;
            this._children.Add(item.ID, item);
        }
    
        public IEnumerator<TreeNode> GetEnumerator()
        {
            return this._children.Values.GetEnumerator();
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    
        public int Count
        {
            get { return this._children.Count; }
        }
    }
    

    Usage will be fairly simple to statically define:

    var tree = new TreeNode("Root")
                   {
                       new TreeNode("Category 1")
                           {
                               new TreeNode("Item 1"),
                               new TreeNode("Item 2"),
                               new TreeNode("Item 3"),
                           },
                       new TreeNode("Category 2")
                           {
                               new TreeNode("Item 1"),
                               new TreeNode("Item 2"),
                               new TreeNode("Item 3"),
                               new TreeNode("Item 4"),
                           }
                   };
    

    Edit

    Some more functionality for even easier creation...

    public static TreeNode BuildTree(string tree)
    {
        var lines = tree.Split(new[] { Environment.NewLine },
                               StringSplitOptions.RemoveEmptyEntries);
    
        var result = new TreeNode("TreeRoot");
        var list = new List<TreeNode> { result };
    
        foreach (var line in lines)
        {
            var trimmedLine = line.Trim();
            var indent = line.Length - trimmedLine.Length;
    
            var child = new TreeNode(trimmedLine);
            list[indent].Add(child);
    
            if (indent + 1 < list.Count)
            {
                list[indent + 1] = child;
            }
            else
            {
                list.Add(child);
            }
        }
    
        return result;
    }
    
    public static string BuildString(TreeNode tree)
    {
        var sb = new StringBuilder();
    
        BuildString(sb, tree, 0);
    
        return sb.ToString();
    }
    
    private static void BuildString(StringBuilder sb, TreeNode node, int depth)
    {
        sb.AppendLine(node.ID.PadLeft(node.ID.Length + depth));
    
        foreach (var child in node)
        {
            BuildString(sb, child, depth + 1);
        }
    }
    


    Usage:

    var tree = TreeNode.BuildTree(@"
    Cat1
     Sub1
      Item1
      Item2
      Item3
     Sub2
      Item1
      Item2
    Cat2
     Sub1
     Sub2
      Item1
      Item2
     Sub3
      Item1
    Cat3
    Cat4");
    
    0 讨论(0)
  • 2020-12-04 09:24

    I created a Node class that could be helpfull. It is fast and has some extra properties, like:

    • Ancestors
    • Descendants
    • Siblings
    • Level of the node
    • Parent
    • Root
    • Etc.
    0 讨论(0)
  • 2020-12-04 09:30

    You can write a simple binary tree , I wrote some Pseudo code beloew:

    class TreeNode {
        TreeNode Right;
        TreeNode Left;
        int id;
        //...
    }
    
    class BinTree {
    
        void Insert(TreeNode node)
        {
            while(true) {   
                if(node.id > target.id) {
                    if(target.Right != null) {
                        target = target.Right;
                        continue;
                    }
                    else {
                        target.Right = node;
                        break;
                    }
                }
    
                else if(node.id < target.id) {
                    if(target.Left != null) {
                        target = target.Left;
                        continue;
                    }
                    else {
                        target.Left = node;
                        break;
                    }   
                }
    
                else {
                    throw new ArgumentException("Duplicated id");
                }
            }
        }
    
    
        TreeNode Search(int id)
        {
            TreeNode target = root;
    
            while(target != null) {
                if(id > target.id) {
                    target = target.Right;
                }
                else if(id < target.id) {
                    target = target.Left;
                }
                else {
                    return target;
                }
            }
    
            return null;
        }
    
    }
    

    But if your data count is very large, maybe AVL tree is more efficient

    0 讨论(0)
提交回复
热议问题