views:

19242

answers:

7

I was looking for a tree or graph data structure in C# but I guess there isn't one provided. http://msdn.microsoft.com/en-us/library/ms379574.aspx explains a bit about why. Is there a convenient library which is commonly used to provide this functionality? Perhaps through a strategy pattern to solve the issues presented in the article.

I feel a bit silly implementing my own tree, just as I would implementing my own ArrayList.

Edit:

I think I need to explain better what I'm looking for. I just want a generic tree which can be unbalanced. Think of a directory tree. C5 looks nifty, but their tree structures seem to be implemented as balanced red-black trees better suited to search than representing a hierarchy of nodes.

+5  A: 

The generally excellent C5 Generic Collection Library has several different tree-based data structures, including sets, bags and dictionaries. Source code is available if you want to study their implementation details. (I have used C5 collections in production code with good results, although I haven't used any of the tree structures specifically.)

McKenzieG1
I was disappointed by the lack of documentation surrounding C5's library, however, it makes sense considering they'd like to sell the book.
sixlettervariables
Don't know if maybe things have changed but right now the book is freely available to download as PDF from the C5 site.
Oskar
Lack of documentation is no more a concern as there's a 272 pages long pdf complementing the library...Can't comment on code quality, but judging from the doc quality, I'm really looking forward to digging into this tonight!
Florian Doyon
+13  A: 

My best advice would be that there is no standard tree data structure because there are so many ways you could implement it that it would be impossible to cover all bases with one solution. The more specific a solution, the less likely it is applicable to any given problem. I even get annoyed with LinkedList - what if I want a circular linked list?

The basic structure you'll need to implement will be a collection of nodes, and here are some options to get you started. Let's assume that the class Node is the base class of the entire solution.

If you need to only navigate down the tree, then a Node class needs a List of children.

If you need to navigate up the tree, then the Node class needs a link to its parent node.

Build an AddChild method that takes care of all the minutia of these two points and any other business logic that must be implemented (child limits, sorting the children, etc.)

David
personally i wouldn't mind some sort of self-balancing binary tree to be added to the library as this is some extra work than just using an adjaceny list.
jk
@jk I believe that SortedDictionary and SortedSet are built atop red/black trees, so using these should work.
jonp
+2  A: 

If you would like to write your own, you can start with this six-part document detailing effective usage of C# 2.0 data structures and how to go about analyzing your implementation of data structures in C#. Each article has examples and an installer with samples you can follow along with.

“An Extensive Examination of Data Structures Using C# 2.0” by Scott Mitchell

sixlettervariables
+25  A: 

I hate to admit it but I ended up writing my own tree class using a linked list. On an unrelated note I just discovered this round thing which, when attached to a thing I'm calling an 'axle' allows for easier transportation of goods.

stimms
+1 for the laughts. :-)
Konrad Rudolph
+5  A: 

I came across this question while looking for the same thing myself. After some googling in found Dan Vanderboom's post and it looks quite promising. I'll give it a try this week-end and I'll post my findings here.

chitza
Still waiting for those findings ;)
AviD
+7  A: 
delegate void TreeVisitor<T>(T nodeData);

    class NTree<T>
    {
        T data;
        LinkedList<NTree<T>> children;

        public NTree(T data)
        {
            this.data = data;
            children = new LinkedList<NTree<T>>();
        }

        public void addChild(T data)
        {
            children.AddFirst(new NTree<T>(data));
        }

        public NTree<T> getChild(int i)
        {
            foreach (NTree<T> n in children)
                if (--i == 0) return n;
            return null;
        }

        public void traverse(NTree<T> node, TreeVisitor<T> visitor)
        {
            visitor(node.data);
            foreach (NTree<T> kid in node.children)
                traverse(kid, visitor);
        }        
    }

Simple recursive implementation... < 40 lines of code... You just need to keep a reference to the root of the tree outside of the class, or wrap it in another class, maybe rename to TreeNode??

+1 this is a good implementation.
chikak
is there a reason for the linked list? I tend to use List<T> or ObservableCollection<T>. What do you get from using the linked list. As an aside, using this method, its really easy to build the Descendants() method on the tree that LINQ to XML has. This is very useful for organizing data based on a predicate.
Steve
In this case, in C# anyway, you could avoid writing your own delegate and use the pre-made `Action<T>` delegate: `public void traverse(NTree<T> node, Action<T> visitor)` . Action<>'s signature is: `void Action<T>( T obj )` . There are also versions from 0 to 4 different parameters. There's also an analogous delegate for functions called `Func<>`.
Benny Jobigan
Yes, but a custom delegate makes the code clearer I think.
Advantage of LinkedList is it is more efficient for the purposes we put it to here, and it only consumes as much memory as it needs for however many child nodes are stored. The only action that would be more efficient with an array based List implementation is the getChild(int), but I would expect that to be invoked sparingly, usually add and traverse will be used, for which LinkedList is ideally suited. Completing the implementation and adding in Remove may complicate things. Be nice if C#s generics allowed the user to specify the List implementation to best suit usage, but it doesnt.
It is a mixup of LinkedList and List, children is of type LinkedList<T> but the methods Add or [] smells of List<T>
Gorgen
You are correct, I just wrote the code straight into the SO editor.Now changed/corrected... (but essentially what an indexer implementation might look like anyway)
+3  A: 

See http://quickgraph.codeplex.com/

QuickGraph provides generic directed/undirected graph datastructures and algorithms for .Net 2.0 and up. QuickGraph comes with algorithms such as depth first seach, breath first search, A* search, shortest path, k-shortest path, maximum flow, minimum spanning tree, least common ancestors, etc... QuickGraph supports MSAGL, GLEE, and Graphviz to render the graphs, serialization to GraphML, etc...

harrydev