473,403 Members | 2,323 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,403 software developers and data experts.

System.Collections.Generic.SortedDictionary - lookup and then iterateto next/previous in o(log(n)) time

Hi,

I am converting an existing native C++ program making heavy use of STL
to C#2.0 with STL usage replaced by the new generic collections. The
conversion has gone well to the point where I am replacing an STL map
instance by a System.Collections.Generic.SortedDictionary instance. In
need the collection to be ordered, and to have o(log(n)) look up - that
is fine so far SortedDictionary.TryGetValue does the job. I also need
the ability after a lookup to iterate to the next and previous values in
o(log(n)) time or better. In STL this is easy because map::find returns
an iterator. However, I can't see how to perform the equivalent
operation for a SortedDictionary in o(log(n)) time. (Enumerating the
whole SortedDictionary is o(n) for both average and worst case.)

Have I missed anything obvious? SortedDictionary seems to be based on a
red-black tree - System.Collections.Generic.TreeSet - so the
data-structure appears to be rich enough, but the public methods of
SortedDictionary do not appear to allow access to the functionality I need.

Thanks in advance for any replies.

Paul Delhanty
Cadcambridge Limited
http://www.cadcambridge.net
Nov 17 '05 #1
6 5917


Paul Delhanty wrote:
Have I missed anything obvious? SortedDictionary seems to be based on a
red-black tree - System.Collections.Generic.TreeSet - so the
data-structure appears to be rich enough, but the public methods of
SortedDictionary do not appear to allow access to the functionality I need.


SortedDictionary can use the natural numbers as an iterator.

You can use IndexOfKey to obtain the index of your item. Then you can
add/subtract from that index and pass it to GetKey and GetByIndex to get
the Key/Value next to the original key.

Note, that you may need to "lock ( dict.SyncRoot )", during these
operations, and that you won't get an exception if the data-structure
changes while you are holding an index, unlike most other iterators in .NET.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #2
Helge Jensen wrote:


Paul Delhanty wrote:
Have I missed anything obvious? SortedDictionary seems to be based on
a red-black tree - System.Collections.Generic.TreeSet - so the
data-structure appears to be rich enough, but the public methods of
SortedDictionary do not appear to allow access to the functionality I
need.

SortedDictionary can use the natural numbers as an iterator.

You can use IndexOfKey to obtain the index of your item. Then you can
add/subtract from that index and pass it to GetKey and GetByIndex to get
the Key/Value next to the original key.

Note, that you may need to "lock ( dict.SyncRoot )", during these
operations, and that you won't get an exception if the data-structure
changes while you are holding an index, unlike most other iterators in
.NET.


Thanks very much for your reply.

I can't seem to find IndexOfKey on SortedDictionary. I can see
IndexOfKey on SortedList, but that is an array based implementation
rather than a red-black tree as per SortedDictionary, so I might expect
something like IndexOfKey.

Thanks for the lock ( dict.SyncRoot ) tip.

Paul Delhanty
Cadcambridge Limited
http://www.cadcambridge.net
Nov 17 '05 #3


Paul Delhanty wrote:
I can't seem to find IndexOfKey on SortedDictionary. I can see
IndexOfKey on SortedList, but that is an array based implementation
rather than a red-black tree as per SortedDictionary, so I might expect
something like IndexOfKey.


Ups, sorry. I obviously mixed up those 2 when reading -- haven't looked
at .NET2 too much yet, so I mistakenly read it as SortedList.

Here are a few ideas for what you could do, although I must admit i
don't really like them as good as just being able to obtain some kind of
iterator at lookup-point from data-structures that have ordering ;)

- If the data is first built and then repeatedly looked up, you can
build the data in a SortedDictionary and when built, copy it to an array
which you can then index using the BinarySearch-functions

- Implement IDictionary<T> by extending SortedDictionary. Use a
seperate hash-table to track previous/next relations.

- Use introspection to get at the implementation of SortedDictionary
and hack up a class that will return a useable iterator. I don't think
the .NET runtime checks privacy, only the C# compiler -- don't quote me
on that though!

- Reimplement SortedDictionary yourself, (you know red/black trees
are just such fun ;) and let it exhibit the methods you need.

- Implement IDictionary<T> using std::map from C++ through the
managed extensions for C++, and expose enough methods to make it work.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #4
Helge Jensen wrote:


Paul Delhanty wrote:
I can't seem to find IndexOfKey on SortedDictionary. I can see
IndexOfKey on SortedList, but that is an array based implementation
rather than a red-black tree as per SortedDictionary, so I might
expect something like IndexOfKey.

Ups, sorry. I obviously mixed up those 2 when reading -- haven't looked
at .NET2 too much yet, so I mistakenly read it as SortedList.

Here are a few ideas for what you could do, although I must admit i
don't really like them as good as just being able to obtain some kind of
iterator at lookup-point from data-structures that have ordering ;)

- If the data is first built and then repeatedly looked up, you can
build the data in a SortedDictionary and when built, copy it to an array
which you can then index using the BinarySearch-functions

- Implement IDictionary<T> by extending SortedDictionary. Use a
seperate hash-table to track previous/next relations.

- Use introspection to get at the implementation of SortedDictionary
and hack up a class that will return a useable iterator. I don't think
the .NET runtime checks privacy, only the C# compiler -- don't quote me
on that though!

- Reimplement SortedDictionary yourself, (you know red/black trees are
just such fun ;) and let it exhibit the methods you need.

- Implement IDictionary<T> using std::map from C++ through the managed
extensions for C++, and expose enough methods to make it work.

Thanks once again for your reply.

I have reordered things so the data is first built and then repeatedly
queried, so I will do as you suggest with copying into an array and
using BinarySearch. That should be pretty efficient - like using a
sorted vector in STL.

As for the other suggestions, I don't really want to get into the
business of building and maintaining my own collections if I can help
it. If I had not been able to use the batch build first and then query
approach, I would probably have had to do one of the other things you
suggested though. Implementing using hash-tables to track previous-next
would probably have been fairly solid, even if less efficient than just
a straight red-black tree. Using introspection was not something that
occurred to me - I guess it would give the same o(log(n)) performance
for inserts etc, though I'm not sure about the constant term. As for
reimplementing, SortedDictionary, I have just reconstructed and built
the source code using Lutz Roeder's Reflector (
http://www.aisto.com/roeder/dotnet/ ), but there is quite a lot and I am
glad that I won't have to maintain it now. Using C++, would work
though, I want to compile everything as safe, so as to be able to run in
a partial trust environment, so it would have had to have been the new
managed STL. I read somewhere recently, (I can't remember where), that
managed STL might not ship with Visual C++ 2005.

Anyway, once again, thanks for your help.
Paul Delhanty
Cadcambridge Limited
http://www.cadcambridge.net
Nov 17 '05 #5


Paul Delhanty wrote:
for inserts etc, though I'm not sure about the constant term. As for
reimplementing, SortedDictionary, I have just reconstructed and built
the source code using Lutz Roeder's Reflector (
http://www.aisto.com/roeder/dotnet/ ), but there is quite a lot and I am


That was a nice and sneaky approach... perhaps you should read the EULA,
just to make sure you're not on shaky ground ;)

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #6
Helge Jensen wrote:


Paul Delhanty wrote:
for inserts etc, though I'm not sure about the constant term. As for
reimplementing, SortedDictionary, I have just reconstructed and built
the source code using Lutz Roeder's Reflector (
http://www.aisto.com/roeder/dotnet/ ), but there is quite a lot and I am

That was a nice and sneaky approach... perhaps you should read the EULA,
just to make sure you're not on shaky ground ;)

Luckily your first suggestion about building the data first and then
querying first worked better anyway, so I was able to throw the
reflector generated code away :-) (I didn't want to maintain it anyway,
as it had a lot of legacy pre-generics stuff in there.)
Paul
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Doug Dew | last post by:
This won't compile: using IEnumerable<T> = System.Collections.Generic.IEnumerable<T>; namespace MyNamespace { public class MyClass<T> : IEnumerable<T> { // Appropriate stuff here }
3
by: Abhi | last post by:
In the following hypothetical example I want to build a generic list of unique string items. How should I implement the pred function so that it returns true/false if target string exists in the...
2
by: ljlevend | last post by:
I've noticed that in VS.NET 2.0 Beta 1 that none of the methods in System.Collections.Generic.List are overridable. In my app I currently have over 50 strongly typed ArrayLists that inherit from...
4
by: nhmark64 | last post by:
Hi, Does System.Collections.Generic.Queue not have a Synchronized method because it is already in effect synchronized, or is the Synchronized functionality missing from...
0
by: Susan | last post by:
I have an issue with the System.Collections.Generic.List that I can't find anywhere else... My website suddenly starts giving off System.IndexOutOfRangeException: Index was outside the bounds of...
2
by: pamela fluente | last post by:
Hi I am doing something like: Dim MiDict As New System.Collections.Generic.Dictionary(Of String, MyObject) how should I change the above so that the string comparison (key) is done using...
2
by: Fred Heida | last post by:
Hi, i'm trying to (using managed C++) implment the IEnumerable<Tinterface on my class.. but have a problem with the 2 GetEnumerator method required.... what i have done is... ...
2
by: confused1234 | last post by:
Hi i'm trying to pass a field of type System.Collections.Generic.ICollection< FeedImage> to a function. I dont't have a clue what this icollection is. but i tried some code ...
0
by: DR | last post by:
System.Collections.Generic.List<intmyList = new System.Collections.Generic.List<int>(100); Does this preallocate 100 integers? Also, is there any way to preallocate an array of objects all at...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.