SortedList 有序线性表
SortedList集合类是有序线性表,本质上是一颗二分查找树。
增
Add操作是通过二分查找到它应该被插入的下标,再通过Insert进行添加。
public void Add(TKey key, TValue value) {
if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
int i = Array.BinarySearch<TKey>(keys, 0, _size, key, comparer);
if (i >= 0)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
Insert(~i, key, value);
}
private void Insert(int index, TKey key, TValue value) {
if (_size == keys.Length) EnsureCapacity(_size + 1);
if (index < _size) {
Array.Copy(keys, index, keys, index + 1, _size - index);
Array.Copy(values, index, values, index + 1, _size - index);
}
keys[index] = key;
values[index] = value;
_size++;
version++;
}
通过Array.BinarySearch查找到当前元素应该插入的位置下标,再调用Insert方法添加到指定的位置。
查
bool System.Collections.IDictionary.Contains(Object key) {
if( IsCompatibleKey(key)) {
return ContainsKey((TKey) key);
}
return false;
}
// Checks if this sorted list contains an entry with the given key.
//
public bool ContainsKey(TKey key) {
return IndexOfKey(key) >= 0;
}
// Checks if this sorted list contains an entry with the given value. The
// values of the entries of the sorted list are compared to the given value
// using the Object.Equals method. This method performs a linear
// search and is substantially slower than the Contains
// method.
//
public bool ContainsValue(TValue value) {
return IndexOfValue(value) >= 0;
}
其Contains方法与Containskey方法通过二分查找检索元素,复杂度是O(lg n),ContainsValue方法是使用线性查找元素,复杂度是O(n)。
public int IndexOfKey(TKey key) {
if (key == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
int ret = Array.BinarySearch<TKey>(keys, 0, _size, key, comparer);
return ret >=0 ? ret : -1;
}
public int IndexOfValue(TValue value) {
return Array.IndexOf(values, value, 0, _size);
}
TryGetValue与索引器通过二分查找检索到指定的key的下标,再借此返回指定的value。
public bool TryGetValue(TKey key, out TValue value) {
int i = IndexOfKey(key);
if (i >= 0) {
value =values[i];
return true;
}
value = default(TValue);
return false;
}
public TValue this[TKey key] {
get {
int i = IndexOfKey(key);
if (i >= 0)
return values[i];
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
}
删
// Removes the entry at the given index. The size of the sorted list is
// decreased by one.
//
public void RemoveAt(int index) {
if (index < 0 || index >= _size) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
_size--;
if (index < _size) {
Array.Copy(keys, index + 1, keys, index, _size - index);
Array.Copy(values, index + 1, values, index, _size - index);
}
keys[_size] = default(TKey);
values[_size] = default(TValue);
version++;
}
// Removes an entry from this sorted list. If an entry with the specified
// key exists in the sorted list, it is removed. An ArgumentException is
// thrown if the key is null.
//
public bool Remove(TKey key) {
int i = IndexOfKey(key);
if (i >= 0)
RemoveAt(i);
return i >= 0;
}
void System.Collections.IDictionary.Remove(Object key) {
if( IsCompatibleKey(key)) {
Remove((TKey) key);
}
}
如果是Remove需要先通过二分查找检索到指定的key的下标,然后再调用RemoveAt方法删除指定的元素。
改
public TValue this[TKey key] {
set {
if (((Object) key) == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
int i = Array.BinarySearch<TKey>(keys, 0, _size, key, comparer);
if (i >= 0) {
values[i] = value;
version++;
return;
}
Insert(~i, key, value);
}
}
二分查找到下标设置值。
本身就是一颗二叉查找树,自身有序,所以无需排序。
关于二叉查找树的更多内容可以查看我之前的文章: