Tim*_*mwi 29 .net sortedlist base-class-library
为什么只有一个SortedList<TKey, TValue>看起来更像是字典,但SortedList<T>实际上只是一个总是排序的列表?
根据有关SortedList的MSDN文档,它实际上是在内部实现为动态大小的数组KeyValuePair<TKey, TValue>,始终按键排序.作为任何类型的列表,同一个类不会更有用T吗?那个名字也不合适吗?
Gab*_*abe 10
虽然没有人能真正告诉你为什么没有SortedList<T>,但有可能讨论为什么SortedList需要一个关键和一个值.字典将键映射到值.执行此操作的典型方法是使用二叉树,哈希表和列表(数组),但哈希表最常见,因为对于大多数操作它们都是O(1).
它在O(1)中不支持的主要操作是按顺序获取下一个键.如果您希望能够这样做,通常使用二叉树,为您提供排序字典.
如果您决定将映射实现为列表,则应保持元素按键排序,以便查找为O(lg n),以排序列表的形式为您提供另一个排序字典.当然这个名字SortedDictionary已经被采用,但SortedList事实并非如此.我可能把它称为SortedListDictionary或SortedDictionaryList,但我没有去命名它.
现在有:)
public class SortedList<T> : ICollection<T>
{
private List<T> m_innerList;
private Comparer<T> m_comparer;
public SortedList() : this(Comparer<T>.Default)
{
}
public SortedList(Comparer<T> comparer)
{
m_innerList = new List<T>();
m_comparer = comparer;
}
public void Add(T item)
{
int insertIndex = FindIndexForSortedInsert(m_innerList, m_comparer, item);
m_innerList.Insert(insertIndex, item);
}
public bool Contains(T item)
{
return IndexOf(item) != -1;
}
/// <summary>
/// Searches for the specified object and returns the zero-based index of the first occurrence within the entire SortedList<T>
/// </summary>
public int IndexOf(T item)
{
int insertIndex = FindIndexForSortedInsert(m_innerList, m_comparer, item);
if (insertIndex == m_innerList.Count)
{
return -1;
}
if (m_comparer.Compare(item, m_innerList[insertIndex]) == 0)
{
int index = insertIndex;
while (index > 0 && m_comparer.Compare(item, m_innerList[index - 1]) == 0)
{
index--;
}
return index;
}
return -1;
}
public bool Remove(T item)
{
int index = IndexOf(item);
if (index >= 0)
{
m_innerList.RemoveAt(index);
return true;
}
return false;
}
public void RemoveAt(int index)
{
m_innerList.RemoveAt(index);
}
public void CopyTo(T[] array)
{
m_innerList.CopyTo(array);
}
public void CopyTo(T[] array, int arrayIndex)
{
m_innerList.CopyTo(array, arrayIndex);
}
public void Clear()
{
m_innerList.Clear();
}
public T this[int index]
{
get
{
return m_innerList[index];
}
}
public IEnumerator<T> GetEnumerator()
{
return m_innerList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return m_innerList.GetEnumerator();
}
public int Count
{
get
{
return m_innerList.Count;
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public static int FindIndexForSortedInsert(List<T> list, Comparer<T> comparer, T item)
{
if (list.Count == 0)
{
return 0;
}
int lowerIndex = 0;
int upperIndex = list.Count - 1;
int comparisonResult;
while (lowerIndex < upperIndex)
{
int middleIndex = (lowerIndex + upperIndex) / 2;
T middle = list[middleIndex];
comparisonResult = comparer.Compare(middle, item);
if (comparisonResult == 0)
{
return middleIndex;
}
else if (comparisonResult > 0) // middle > item
{
upperIndex = middleIndex - 1;
}
else // middle < item
{
lowerIndex = middleIndex + 1;
}
}
// At this point any entry following 'middle' is greater than 'item',
// and any entry preceding 'middle' is lesser than 'item'.
// So we either put 'item' before or after 'middle'.
comparisonResult = comparer.Compare(list[lowerIndex], item);
if (comparisonResult < 0) // middle < item
{
return lowerIndex + 1;
}
else
{
return lowerIndex;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为解决这个问题的方法是实现一个List<T>以排序方式添加的扩展方法(只需 2 行代码;),然后List<T>可以用作排序列表(假设您避免使用List.Add(...)):
public static void AddSorted<T>(this List<T> list, T value)
{
int x = list.BinarySearch(value);
list.Insert((x >= 0) ? x : ~x, value);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11812 次 |
| 最近记录: |