I need to write some code for linear interpolation and I am trying to figure out the most efficient way to search the Keys of a SortedList<K, V>
for the upper and lower keys that surround my target key.
SortedList<int, double> xyTable = new SortedList<int, double>()
{
{1, 10}, {2, 20}, {3, 30}, {4,40}
};
double targetX = 3.5;
What is the most efficient way to search the list and determine that 3.5 is between 3 and 4? I have a method / cheat that works for integers (temporarily insert the target Key into the list then find the index) but I figured I'd ask the pros so I could produce quality code.
Thanks.
A SortedList in C# is a collection of key-value pairs that must be sorted at any given point in time based on its keys. This data structure guarantees that whenever we add or remove elements from any point in the list, the order of the list will remain the same.
In C#, SortedList is a collection of key/value pairs which are sorted according to keys. By default, this collection sort the key/value pairs in ascending order. It is of both generic and non-generic type of collection. The generic SortedList is defined in System.
Binary search, also known as half-interval search, is one of the common search algorithms that find the position of a value within a sorted array. The search algorithm looks for a value in a sorted array and starts at the middle element and compares the value with the item of the array.
The SortedList class represents a collection of key-and-value pairs that are sorted by the keys and are accessible by key and by index. A sorted list is a combination of an array and a hash table. It contains a list of items that can be accessed using a key or an index.
A binary search gives you decent performance on a list. However the Keys property on SortedList
is of type IList
, whereas BinarySearch
is defined on List
. Fortunately, you can find an implementation of binary search for IList
in this related question:
How to perform a binary search on IList<T>?
In my case the source SortedList
is not changing much, since its being used as a lookup table. So in this case it makes sense to convert the SortedList
to a List<T>
once. After that it is quite easy to use the built-in BinarySearch method of List<T>
...
double targetX = 3.5;
// Assume keys are doubles, may need to convert to doubles if required here.
// The below line should only be performed sparingly as it is an O(n) operation.
// In my case I only do this once, as the list is unchanging.
List<double> keys = xyTable.Keys.ToList();
int ipos = keys.BinarySearch(targetX);
if (ipos >= 0)
{
// exact target found at position "ipos"
}
else
{
// Exact key not found: BinarySearch returns negative when the
// exact target is not found, which is the bitwise complement
// of the next index in the list larger than the target.
ipos = ~ipos;
if (ipos >= 0 && ipos < keys.Count)
{
if (ipos > 0)
{
// target is between positions "ipos-1" and "ipos"
}
else
{
// target is below position "ipos"
}
}
else
{
// target is above position "ipos"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With