80

Is there a built-in binary search tree in .NET 4.0, or do I need to build this abstract data type from scratch?

Edit

This is about the binary search tree specifically, and not abstract data type "trees" in general.

Community
  • 1
  • 1
Benny Skogberg
  • 10,431
  • 11
  • 53
  • 83
  • Possible duplicate of [Objects that represent trees](http://stackoverflow.com/questions/1806511/objects-that-represent-trees) – Robert MacLean Jun 28 '16 at 06:16
  • 1
    Yeah and you knew that six years ago too: http://stackoverflow.com/a/3262982/53236 :P – Robert MacLean Jun 28 '16 at 06:22
  • 1
    @RobertMacLean ... and since then, .NET have evolved and last year I learnt the real answer is YES http://stackoverflow.com/a/34083290/286244 :) – Benny Skogberg Jun 28 '16 at 06:25
  • 2
    Then based on the fact that StackOverflow is editable, shouldn't someone come back and edit these or close these? Basically by leaving an old incorrect/incomplete answer aren't we hurting future hunters of knowledge? – Robert MacLean Jun 28 '16 at 14:18
  • https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.binarysearch?view=netframework-4.7.2 – BigChief Mar 09 '19 at 23:30
  • Thank you for asking this question. Unfortunately the answers here did not suit my needs. E.g. the SortedSet _uses_ a binary search tree (BST) but it is not a BST because it does not expose the classical BST methods and properties. For this reason I have implemented a [library](https://github.com/m31coding/M31.BinarySearchTrees) from scratch. – kmschaal Jun 08 '22 at 16:37

6 Answers6

76

I think the SortedSet<T> class in System.Collections.Generic is what you're looking for.

From this CodeProject article:

It is implemented using a self-balancing red-black tree that gives a performance complexity of O(log n) for insert, delete, and lookup. It is used to keep the elements in sorted order, to get the subset of elements in a particular range, or to get the Min or Max element of the set.

Source code https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/Generic/SortedSet.cs

Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
herzmeister
  • 11,101
  • 2
  • 41
  • 51
  • 2
    A Red-Black Tree is really a specialized kind of Binary Search Tree. See my answer for more details. – Muhammad Rehan Saeed Jan 23 '15 at 11:49
  • 15
    Unfortunatly this class doesn't provide many useful methods of classic Binary Search Tree, e. g. lower_bound (which is implemented in `std::set` in C++). Beware of GetViewBetween method. Unexpectedly it has [linear running time](http://stackoverflow.com/questions/9850975/why-sortedsett-getviewbetween-isnt-olog-n) – renadeen Jul 13 '15 at 21:06
  • This answer is wrong. SortedSet is not a BST. The insert and delete have a time-complexity of O(n). – ataravati Jan 26 '18 at 01:13
  • 1
    SortedSet is a Binary Search Tree. dotnet opensource code is available on github for reference. https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/Generic/SortedSet.cs – Ravi Sankar Rao Jul 07 '18 at 23:40
  • This uses binary search on list https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.binarysearch?view=netframework-4.7.2 – BigChief Mar 09 '19 at 23:31
  • Should `SortedSet.First()` return the root node of the BST? If not, is it returning the first item that was added? Or the one that was added last? – joym8 Mar 13 '19 at 18:23
22

Five years after I asked the question I realized that there is indeed a built in Binary Search Tree in .NET 4.0. It has probably been added later on, and works as expected. It self-balances (traversing) after each insert which decrease performance on adding a large range of items.

The SortedDictionary<TKey, TValue> Class has the following remarks:

The SortedDictionary generic class is a binary search tree with O(log n) retrieval, where n is the number of elements in the dictionary. In this respect, it is similar to the SortedList generic class. The two classes have similar object models, and both have O(log n) retrieval.

Benny Skogberg
  • 10,431
  • 11
  • 53
  • 83
10

No, .NET does not contain a Binary Search Tree. It does contain a Red-Black Tree which is a specialized kind of Binary Search Tree in which each node is painted red or black and there are certain rules using these colours which keep the tree balanced and allows the tree to guarantee O(logn) search times. A standard Binary Search Tree cannot guarantee these search times.

The class is called a SortedSet<T> and was introduced in .NET 4.0. You can look at it's source code here. Here is an example of it's use:

// Created sorted set of strings.
var set = new SortedSet<string>();

// Add three elements.
set.Add("net");
set.Add("net");  // Duplicate elements are ignored.
set.Add("dot");
set.Add("rehan");

// Remove an element.
set.Remove("rehan");

// Print elements in set.
foreach (var value in set)
{
    Console.WriteLine(value);
}

// Output is in alphabetical order:
// dot
// net
Muhammad Rehan Saeed
  • 35,627
  • 39
  • 202
  • 311
4

The C5 collections library (see http://www.itu.dk/research/c5/) includes TreeDictionary<> classes with balanced red-black binary trees. Note: I have not used this library yet, as the work I do needs nothing more that the standard .NET collections.

Dr Herbie
  • 3,930
  • 1
  • 25
  • 28
  • Nice one. Red-Black trees are a little different than ordinary BinarySearchTrees, but still a very nice algorithm! I'll bookmark that link right away, and save it on my XMarks account :) Thanx Dr Herbie. – Benny Skogberg Jul 16 '10 at 08:45
2

Thanx to herzmeister der welten, I now know there are! I tried it and it really worked!

namespace Tree
{
    public partial class Form1 : Form
    {
        private SortedSet<int> binTree = new SortedSet<int>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Insert(int no)
        {
            binTree.Add(no);
        }

        private void Print()
        {
            foreach (int i in binTree)
            {
                Console.WriteLine("\t{0}", i);
            }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            Insert(Int32.Parse(tbxValue.Text));
            tbxValue.Text = "";
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            Print();
        }
    }
}
Benny Skogberg
  • 10,431
  • 11
  • 53
  • 83
0

I'm not sure what exactly you mean with 'tree', but you can do binary searchs on the List class.

public int BinarySearch( T item );
public int BinarySearch( T item, IComparer<T> comparer );
public int BinarySearch( int index, int count, T item, IComparer<T> comparer );
Trap
  • 12,050
  • 15
  • 55
  • 67