I'm converting some C++ code to C# and it calls std::map::lower_bound(k) to find an entry in the map whose key is equal to or greater than k. However, I don't see any way to do the same thing with .NET's SortedDictionary. I suspect I could implement a workaround using SortedList, but unfortunately SortedList is too slow (O(n) for inserting and deleting keys). What can I do?
Note: I found a workaround using that takes advantage of my particular scenario... Specifically, my keys are a dense population of integers starting at just over 0, so I used a List<TValue> as my dictionary with the list index serving as the key, and searching for a key equal or greater than k can be done in only a few loop iterations. But it would still be nice to see the original question answered.
There isn't a binary search tree collection implementation in the base framework, so you'll either have to build one or find an implementation. As you noted, SortedList is closest in terms of searching but is slower (due to its underlying array implementation) for insertion/deletion.
It took a couple months of work, but at last I can offer at least a partial solution to this problem... I call it the Compact Patricia Trie, a sorted dictionary that offers a "find next larger key" operation.
http://www.codeproject.com/KB/recipes/cptrie.aspx
It's only a partial solution since only certain kinds of keys are supported, namely
byte[]
,string
, and all primitive integer types (Int8..UInt64). Also, string sorting is case-sensitive.You can do this for
SortedSet<T>
with following extension methods:I created three data structures related to B+ trees that provide this functionality for any data type:
BList<T>
,BDictionary<K,V>
andBMultiMap<K,V>
. Each of these data structures provideFindLowerBound()
andFindUpperBound()
methods that work like C++'slower_bound
andupper_bound
.I think there's a mistake in the question about SortedList complexity.
SortedList has O(log(n)) amortized complexity for inserting new item. If you know in advance the capacity it can be done in O(Log(n)) in the worst case.
You can try the code i wrote below. it using binary search, therefore assuming the list/array is pre-sorted.