二进制搜索列表

时间:2014-11-21 17:18:56

标签: c# list binary-search

我有以下代码,根据IP地址获取国家/地区ID:

countryID = GetAllCountryIPRanges().Single(c => c.BeginIPNum <= intIp && intIp <= c.EndIPNum).CountryID;

不幸的是,它的速度非常慢,因为有大约200,000条记录。范围不重叠,GetAllCountryIPRanges()BeginIPNum按升序排列。

如何在此列表中实现.BinarySearch()以找到正确的记录?

2 个答案:

答案 0 :(得分:1)

List有一个二进制搜索方法,但由于二进制搜索很容易实现,因为你需要定义的IComparator是如此复杂,因为范围我建议你实现二进制搜索方法

像这样的东西(没试过!)

public static IPRange BinarySearch(List<IPRange> source, int intIp)
{
    int startIndex = 0;
    int endIndex = source.Count;
    while (endIndex >= startIndex)
    {
        int middleIndex = startIndex + (endIndex - startIndex) / 2;
        if (source[middleIndex].BeginIPNum <= intIp && intIp <= source[middleIndex].EndIPNum)
        {
            return source[middleIndex];
        }
        else if (source[middleIndex].BeginIPNum < intIp)
        {
            startIndex = middleIndex + 1;
        }
        else
        {
            endIndex = middleIndex - 1;
        }
    }

    return null;
}

假设列表已排序且没有重叠范围。

答案 1 :(得分:-1)

喜欢递归的优雅......(未经测试)

public static IPRange BinarySearch(IList<IPRange> ipList, int ip)
{
   return BinarySearch(source, ip, 0, ipList.Count - 1);
}

public static IPRange BinarySearch(IList<IPRange> ipList, int ip, int min, int max)
{      
   if (min > max)
   {
     throw new Assertion("Error: ipList is empty, out-of-order, or does not contain an element that includes the IP");
   } 
   int mid = (min + max) / 2;
   var midIp = ipList[mid];
   if (ip < midIp.BeginIpNum)
   {
     return BinarySearch(ipList, ip, min, mid-1);
   }
   if (ip > midIp.EndIpNum)
   {
     return BinarySearch(ipList, ip, mid+1, max);
   }
   return midIp; 
}