Skip to content

Commit

Permalink
Dictionary: SearchAround
Browse files Browse the repository at this point in the history
  • Loading branch information
Nixill committed Jun 13, 2021
1 parent 6742a22 commit ebea75d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 38 deletions.
14 changes: 12 additions & 2 deletions CSharp.Nixill/src/Collections/AVLTree/AVLTreeDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class AVLTreeDictionary<K, V> : INavigableDictionary<K, V> {
#region Implementing IDictionary<K, V>
public V this[K key] {
get {
AVLTreeSet<KeyValuePair<K, V>>.NodeTriplet nodes = BackingSet.SearchAround(new KeyValuePair<K, V>(key, DefaultValue));
NodeTriplet<KeyValuePair<K, V>> nodes = BackingSet.SearchAround(new KeyValuePair<K, V>(key, DefaultValue));
if (nodes.HasEqualValue) {
return nodes.EqualValue.Value;
}
Expand Down Expand Up @@ -80,6 +80,16 @@ public AVLTreeDictionary(IEnumerable<KeyValuePair<K, V>> elems, Comparison<K> co
#region Public Methods
/// Documented in GitHub.
public bool IsEmpty() => BackingSet.IsEmpty();

public NodeTriplet<KeyValuePair<K, V>> EntriesAround(K from) => BackingSet.SearchAround(new KeyValuePair<K, V>(from, default(V)));

public NodeTriplet<K> KeysAround(K from) {
var entries = EntriesAround(from);
var lesser = (entries.HasLesserValue) ? new AVLTreeSet<K>.Node<K> { Data = entries.LesserValue.Key } : null;
var equal = (entries.HasLesserValue) ? new AVLTreeSet<K>.Node<K> { Data = entries.LesserValue.Key } : null;
var greater = (entries.HasLesserValue) ? new AVLTreeSet<K>.Node<K> { Data = entries.LesserValue.Key } : null;
return new NodeTriplet<K>((lesser, equal, greater));
}
#endregion

#region Interface Implementations
Expand Down Expand Up @@ -239,7 +249,7 @@ public void Add(K key, V value) {

// Documented in GitHub.
public bool TryGetValue(K key, out V value) {
AVLTreeSet<KeyValuePair<K, V>>.NodeTriplet nodes = BackingSet.SearchAround(new KeyValuePair<K, V>(key, DefaultValue));
NodeTriplet<KeyValuePair<K, V>> nodes = BackingSet.SearchAround(new KeyValuePair<K, V>(key, DefaultValue));
if (nodes.HasEqualValue) {
value = nodes.EqualValue.Value;
return true;
Expand Down
71 changes: 35 additions & 36 deletions CSharp.Nixill/src/Collections/AVLTree/AVLTreeSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ public void Print() {
/// Returns the value requested if the collection contains it, as well
/// as the next higher and lower values.
/// </summary>
public NodeTriplet SearchAround(T value) {
return new NodeTriplet(SearchBounded(value));
public NodeTriplet<T> SearchAround(T value) {
return new NodeTriplet<T>(SearchBounded(value));
}

/// <summary>
Expand Down Expand Up @@ -1072,51 +1072,50 @@ public void Visit(VisitNodeHandler<Node<TElem>> visitor, int level) {
#endregion
}

#endregion
}

public class NodeTriplet {
private readonly NodeValue Lesser;
private readonly NodeValue Equal;
private readonly NodeValue Greater;
public class NodeTriplet<T> {
internal readonly NodeValue Lesser;
internal readonly NodeValue Equal;
internal readonly NodeValue Greater;

public bool HasLesserValue => Lesser != null;
public bool HasEqualValue => Equal != null;
public bool HasGreaterValue => Greater != null;
public bool HasLesserValue => Lesser != null;
public bool HasEqualValue => Equal != null;
public bool HasGreaterValue => Greater != null;

public T LesserValue {
get {
if (HasLesserValue) return Lesser.Value;
else throw new InvalidOperationException("No lesser value exists.");
}
public T LesserValue {
get {
if (HasLesserValue) return Lesser.Value;
else throw new InvalidOperationException("No lesser value exists.");
}
}

public T EqualValue {
get {
if (HasEqualValue) return Equal.Value;
else throw new InvalidOperationException("No equal value exists.");
}
public T EqualValue {
get {
if (HasEqualValue) return Equal.Value;
else throw new InvalidOperationException("No equal value exists.");
}
}

public T GreaterValue {
get {
if (HasGreaterValue) return Greater.Value;
else throw new InvalidOperationException("No greater value exists.");
}
public T GreaterValue {
get {
if (HasGreaterValue) return Greater.Value;
else throw new InvalidOperationException("No greater value exists.");
}
}

internal NodeTriplet((AVLTreeSet<T>.Node<T> L, AVLTreeSet<T>.Node<T> E, AVLTreeSet<T>.Node<T> G) nodes) {
if (nodes.L != null) Lesser = new NodeValue(nodes.L.Data);
if (nodes.E != null) Equal = new NodeValue(nodes.E.Data);
if (nodes.G != null) Greater = new NodeValue(nodes.G.Data);
}
internal NodeTriplet((AVLTreeSet<T>.Node<T> L, AVLTreeSet<T>.Node<T> E, AVLTreeSet<T>.Node<T> G) nodes) {
if (nodes.L != null) Lesser = new NodeValue(nodes.L.Data);
if (nodes.E != null) Equal = new NodeValue(nodes.E.Data);
if (nodes.G != null) Greater = new NodeValue(nodes.G.Data);
}

private class NodeValue {
public readonly T Value;
public NodeValue(T val) {
Value = val;
}
internal class NodeValue {
public readonly T Value;
public NodeValue(T val) {
Value = val;
}
}

#endregion
}
}

0 comments on commit ebea75d

Please sign in to comment.