|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public class SplayTree<TKey, TValue> : IDictionary<TKey, TValue> where TKey : IComparable<TKey> { |
|
|
|
private SplayTreeNode root; |
|
|
|
private int count; |
|
|
|
private int version = 0; |
|
|
|
SplayTreeNode root; |
|
|
|
int count; |
|
|
|
int version = 0; |
|
|
|
|
|
|
|
public void Add(TKey key, TValue value) { |
|
|
|
this.Set(key, value, throwOnExisting: true); |
|
|
|
|
|
|
this.Set(item.Key, item.Value, throwOnExisting: true); |
|
|
|
} |
|
|
|
|
|
|
|
private void Set(TKey key, TValue value, bool throwOnExisting) { |
|
|
|
void Set(TKey key, TValue value, bool throwOnExisting) { |
|
|
|
if (this.count == 0) { |
|
|
|
this.version++; |
|
|
|
this.root = new SplayTreeNode(key, value); |
|
|
|
|
|
|
n.LeftChild = this.root.LeftChild; |
|
|
|
n.RightChild = this.root; |
|
|
|
this.root.LeftChild = null; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
n.RightChild = this.root.RightChild; |
|
|
|
n.LeftChild = this.root; |
|
|
|
this.root.RightChild = null; |
|
|
|
|
|
|
|
|
|
|
this.Splay(item.Key); |
|
|
|
|
|
|
|
return item.Key.CompareTo(this.root.Key) == 0 && (object.ReferenceEquals(this.root.Value, item.Value) || (!object.ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value))); |
|
|
|
return item.Key.CompareTo(this.root.Key) == 0 && |
|
|
|
(ReferenceEquals(this.root.Value, item.Value) || |
|
|
|
(!ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value))); |
|
|
|
} |
|
|
|
|
|
|
|
public KeyValuePair<TKey, TValue> First() { |
|
|
|
|
|
|
} |
|
|
|
while (t.LeftChild != null) |
|
|
|
t = t.LeftChild; |
|
|
|
|
|
|
|
while (t.LeftChild != null) { |
|
|
|
t = t.LeftChild; |
|
|
|
} |
|
|
|
|
|
|
|
return new KeyValuePair<TKey, TValue>(t.Key, t.Value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
return new KeyValuePair<TKey, TValue>(default(TKey), default(TValue)); |
|
|
|
} |
|
|
|
while (t.LeftChild != null) |
|
|
|
|
|
|
|
while (t.LeftChild != null) { |
|
|
|
} |
|
|
|
|
|
|
|
return new KeyValuePair<TKey, TValue>(t.Key, t.Value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
throw new NullReferenceException("The root of this tree is null!"); |
|
|
|
} |
|
|
|
while (t.RightChild != null) |
|
|
|
|
|
|
|
while (t.RightChild != null) { |
|
|
|
} |
|
|
|
|
|
|
|
return new KeyValuePair<TKey, TValue>(t.Key, t.Value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
return new KeyValuePair<TKey, TValue>(default(TKey), default(TValue)); |
|
|
|
} |
|
|
|
while (t.RightChild != null) |
|
|
|
|
|
|
|
while (t.RightChild != null) { |
|
|
|
} |
|
|
|
|
|
|
|
private void Splay(TKey key) { |
|
|
|
void Splay(TKey key) { |
|
|
|
SplayTreeNode l, r, t, y, header; |
|
|
|
l = r = header = new SplayTreeNode(default(TKey), default(TValue)); |
|
|
|
t = this.root; |
|
|
|
|
|
|
if (t.LeftChild == null) break; |
|
|
|
if (t.LeftChild == null) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (t.LeftChild == null) break; |
|
|
|
if (t.LeftChild == null) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} else if (c > 0) { |
|
|
|
if (t.RightChild == null) break; |
|
|
|
} |
|
|
|
else if (c > 0) { |
|
|
|
if (t.RightChild == null) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (t.RightChild == null) break; |
|
|
|
if (t.RightChild == null) { |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
l.RightChild = t.LeftChild; |
|
|
|
r.LeftChild = t.RightChild; |
|
|
|
t.LeftChild = header.RightChild; |
|
|
|
|
|
|
|
|
|
|
if (this.root.LeftChild == null) { |
|
|
|
this.root = this.root.RightChild; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
var swap = this.root.RightChild; |
|
|
|
this.root = this.root.LeftChild; |
|
|
|
this.Splay(key); |
|
|
|
|
|
|
return this.root.Value; |
|
|
|
} |
|
|
|
|
|
|
|
set { |
|
|
|
this.Set(key, value, throwOnExisting: false); |
|
|
|
} |
|
|
|
set { this.Set(key, value, throwOnExisting: false); } |
|
|
|
} |
|
|
|
|
|
|
|
public int Count { |
|
|
|
|
|
|
|
|
|
|
this.Splay(item.Key); |
|
|
|
|
|
|
|
if (item.Key.CompareTo(this.root.Key) == 0 && (object.ReferenceEquals(this.root.Value, item.Value) || (!object.ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value)))) { |
|
|
|
if (item.Key.CompareTo(this.root.Key) == 0 && (ReferenceEquals(this.root.Value, item.Value) || |
|
|
|
(!ReferenceEquals(item.Value, null) && |
|
|
|
item.Value.Equals(this.root.Value)))) { |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
var swap = this.root.RightChild; |
|
|
|
this.root = this.root.LeftChild; |
|
|
|
this.Splay(item.Key); |
|
|
|
|
|
|
|
|
|
|
if (depth == 0) { |
|
|
|
this.Clear(); |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
var prevCount = this.count; |
|
|
|
this.count = this.Trim(this.root, depth - 1); |
|
|
|
if (prevCount != this.count) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
private int Trim(SplayTreeNode node, int depth) { |
|
|
|
int Trim(SplayTreeNode node, int depth) { |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
count += Trim(node.LeftChild, depth - 1); |
|
|
|
count += this.Trim(node.LeftChild, depth - 1); |
|
|
|
count += Trim(node.RightChild, depth - 1); |
|
|
|
count += this.Trim(node.RightChild, depth - 1); |
|
|
|
} |
|
|
|
|
|
|
|
return count; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { |
|
|
|
return new TiedList<KeyValuePair<TKey, TValue>>(this, this.version, this.AsList(node => new KeyValuePair<TKey, TValue>(node.Key, node.Value))).GetEnumerator(); |
|
|
|
return new TiedList<KeyValuePair<TKey, TValue>>(this, this.version, |
|
|
|
this.AsList(node => new KeyValuePair<TKey, TValue>(node.Key, node.Value))).GetEnumerator(); |
|
|
|
private IList<TEnumerator> AsList<TEnumerator>(Func<SplayTreeNode, TEnumerator> selector) { |
|
|
|
IList<TEnumerator> AsList<TEnumerator>(Func<SplayTreeNode, TEnumerator> selector) { |
|
|
|
PopulateList(this.root, result, selector); |
|
|
|
this.PopulateList(this.root, result, selector); |
|
|
|
private void PopulateList<TEnumerator>(SplayTreeNode node, List<TEnumerator> list, Func<SplayTreeNode, TEnumerator> selector) { |
|
|
|
if (node.LeftChild != null) PopulateList(node.LeftChild, list, selector); |
|
|
|
void PopulateList<TEnumerator>(SplayTreeNode node, List<TEnumerator> list, |
|
|
|
Func<SplayTreeNode, TEnumerator> selector) { |
|
|
|
if (node.LeftChild != null) { |
|
|
|
this.PopulateList(node.LeftChild, list, selector); |
|
|
|
} |
|
|
|
|
|
|
|
if (node.RightChild != null) PopulateList(node.RightChild, list, selector); |
|
|
|
if (node.RightChild != null) { |
|
|
|
this.PopulateList(node.RightChild, list, selector); |
|
|
|
} |
|
|
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { |
|
|
|
IEnumerator IEnumerable.GetEnumerator() { |
|
|
|
private sealed class SplayTreeNode { |
|
|
|
sealed class SplayTreeNode { |
|
|
|
public readonly TKey Key; |
|
|
|
|
|
|
|
public TValue Value; |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private sealed class TiedList<T> : IList<T> { |
|
|
|
private readonly SplayTree<TKey, TValue> tree; |
|
|
|
private readonly int version; |
|
|
|
private readonly IList<T> backingList; |
|
|
|
sealed class TiedList<T> : IList<T> { |
|
|
|
readonly SplayTree<TKey, TValue> tree; |
|
|
|
readonly int version; |
|
|
|
readonly IList<T> backingList; |
|
|
|
|
|
|
|
public TiedList(SplayTree<TKey, TValue> tree, int version, IList<T> backingList) { |
|
|
|
if (tree == null) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public int IndexOf(T item) { |
|
|
|
if (this.tree.version != this.version) throw new InvalidOperationException("The collection has been modified."); |
|
|
|
if (this.tree.version != this.version) { |
|
|
|
throw new InvalidOperationException("The collection has been modified."); |
|
|
|
} |
|
|
|
|
|
|
|
return this.backingList.IndexOf(item); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public T this[int index] { |
|
|
|
get { |
|
|
|
if (this.tree.version != this.version) throw new InvalidOperationException("The collection has been modified."); |
|
|
|
if (this.tree.version != this.version) { |
|
|
|
throw new InvalidOperationException("The collection has been modified."); |
|
|
|
} |
|
|
|
|
|
|
|
set { |
|
|
|
throw new NotSupportedException(); |
|
|
|
} |
|
|
|
set { throw new NotSupportedException(); } |
|
|
|
} |
|
|
|
|
|
|
|
public void Add(T item) { |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public bool Contains(T item) { |
|
|
|
if (this.tree.version != this.version) throw new InvalidOperationException("The collection has been modified."); |
|
|
|
if (this.tree.version != this.version) { |
|
|
|
throw new InvalidOperationException("The collection has been modified."); |
|
|
|
} |
|
|
|
|
|
|
|
if (this.tree.version != this.version) throw new InvalidOperationException("The collection has been modified."); |
|
|
|
if (this.tree.version != this.version) { |
|
|
|
throw new InvalidOperationException("The collection has been modified."); |
|
|
|
} |
|
|
|
|
|
|
|
this.backingList.CopyTo(array, arrayIndex); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public IEnumerator<T> GetEnumerator() { |
|
|
|
if (this.tree.version != this.version) throw new InvalidOperationException("The collection has been modified."); |
|
|
|
if (this.tree.version != this.version) { |
|
|
|
throw new InvalidOperationException("The collection has been modified."); |
|
|
|
} |
|
|
|
if (this.tree.version != this.version) throw new InvalidOperationException("The collection has been modified."); |
|
|
|
if (this.tree.version != this.version) { |
|
|
|
throw new InvalidOperationException("The collection has been modified."); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |