Dot-Net

如何對 IList<T> 執行二進制搜尋?

  • June 8, 2009

簡單的問題 - 給出一個IList&lt;T&gt;如何在不自己編寫方法並且不將數據複製到具有內置二進制搜尋支持的類型的情況下執行二進制搜尋的問題。我現在的狀態如下。

  • List&lt;T&gt;.BinarySearch()不是IList&lt;T&gt;
  • 沒有等效的ArrayList.Adapter()方法List&lt;T&gt;
  • IList&lt;T&gt;不繼承自IList,因此ArrayList.Adapter()無法使用

我傾向於認為使用內置方法是不可能的,但我無法相信 BCL/FCL 中缺少這種基本方法。

如果不可能,誰能給出最短、最快、最聰明或最漂亮的二分搜尋實現IList&lt;T&gt;

更新

我們都知道在使用二分搜尋之前必須對列表進行排序,因此您可以假設它是。但我認為(但沒有驗證)排序是同樣的問題 - 你如何排序IList&lt;T&gt;

結論

似乎沒有內置的二進制搜尋IList&lt;T&gt;。可以使用LINQ 方法進行搜尋和排序,但它可能會影響性能First()OrderBy()自己實現它(作為擴展方法)似乎是你能做的最好的。

我懷疑.NET中是否存在類似的通用二進制搜尋方法,除了某些基類中存在的方法(但顯然不在介面中),所以這是我的通用方法。

public static Int32 BinarySearchIndexOf&lt;T&gt;(this IList&lt;T&gt; list, T value, IComparer&lt;T&gt; comparer = null)
{
   if (list == null)
       throw new ArgumentNullException(nameof(list));

   comparer = comparer ?? Comparer&lt;T&gt;.Default;

   Int32 lower = 0;
   Int32 upper = list.Count - 1;

   while (lower &lt;= upper)
   {
       Int32 middle = lower + (upper - lower) / 2;
       Int32 comparisonResult = comparer.Compare(value, list[middle]);
       if (comparisonResult == 0)
           return middle;
       else if (comparisonResult &lt; 0)
           upper = middle - 1;
       else
           lower = middle + 1;
   }

   return ~lower;
}

這當然假設有問題的列表已經按照比較器將使用的相同規則進行了排序。

引用自:https://stackoverflow.com/questions/967047