Skip to content

Commit

Permalink
Fixed Issue aalhour#137 Items are not always added to a SkipList
Browse files Browse the repository at this point in the history
  • Loading branch information
Gutsonok committed Aug 5, 2020
1 parent 504140e commit f769be0
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 53 deletions.
47 changes: 24 additions & 23 deletions DataStructures/Lists/SkipList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,6 @@ public class SkipList<T> : ICollection<T>, IEnumerable<T> where T : IComparable<
private readonly int MaxLevel = 32;
private readonly double Probability = 0.5;


/// <summary>
/// Private helper. Used in Add method.
/// </summary>
/// <returns></returns>
private int _getNextLevel()
{
int lvl = 0;

while (_randomizer.NextDouble() < Probability && lvl <= _currentMaxLevel && lvl < MaxLevel)
++lvl;

return lvl;
}


/// <summary>
/// CONSTRUCTOR
/// </summary>
Expand Down Expand Up @@ -94,12 +78,15 @@ public int Level
/// <summary>
/// Access elements by index
/// </summary>
public T this[int index]
public T this[T item]
{
get
{
// TODO:
throw new NotImplementedException();
return Find(item, out var result) ? result : throw new KeyNotFoundException();
}
set
{
Add(item);
}
}

Expand All @@ -119,8 +106,6 @@ public void Add(T item)
toBeUpdated[i] = current;
}

current = current.Forwards[0];

// Get the next node level, and update list level if required.
int lvl = _getNextLevel();
if (lvl > _currentMaxLevel)
Expand Down Expand Up @@ -150,8 +135,7 @@ public void Add(T item)
/// </summary>
public bool Remove(T item)
{
T deleted;
return Remove(item, out deleted);
return Remove(item, out var _);
}

/// <summary>
Expand Down Expand Up @@ -185,8 +169,12 @@ public bool Remove(T item, out T deleted)
// We know that the node is in the list.
// Unlink it from the levels where it exists.
for (int i = 0; i < _currentMaxLevel; ++i)
{
if (toBeUpdated[i].Forwards[i] == current)
{
toBeUpdated[i].Forwards[i] = current.Forwards[i];
}
}

// Decrement the count
--_count;
Expand Down Expand Up @@ -367,6 +355,19 @@ public void Clear()
}
#endregion

/// <summary>
/// Private helper. Used in Add method.
/// </summary>
/// <returns></returns>
private int _getNextLevel()
{
int lvl = 1;

while (_randomizer.NextDouble() < Probability && lvl <= _currentMaxLevel && lvl < MaxLevel)
++lvl;

return lvl;
}
}

}
20 changes: 3 additions & 17 deletions DataStructures/Lists/SkipListNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ namespace DataStructures.Lists
{
public class SkipListNode<T> : IComparable<SkipListNode<T>> where T : IComparable<T>
{
/// <summary>
/// Instance variables
/// </summary>
private T _value;
private SkipListNode<T>[] _forwards;

/// <summary>
/// CONSTRUCTORS
/// </summary>
Expand All @@ -25,20 +19,12 @@ public SkipListNode(T value, int level)
/// <summary>
/// Get and set node's value
/// </summary>
public virtual T Value
{
get { return this._value; }
private set { this._value = value; }
}
public virtual T Value { get; private set; }

/// <summary>
/// Get and set node's forwards links
/// </summary>
public virtual SkipListNode<T>[] Forwards
{
get { return this._forwards; }
private set { this._forwards = value; }
}
public virtual SkipListNode<T>[] Forwards { get; private set; }

/// <summary>
/// Return level of node.
Expand All @@ -55,7 +41,7 @@ public int CompareTo(SkipListNode<T> other)
{
if (other == null)
return -1;

return this.Value.CompareTo(other.Value);
}
}
Expand Down
83 changes: 70 additions & 13 deletions UnitTest/DataStructuresTests/SkipListTest.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,92 @@
using DataStructures.Lists;
using System.Collections.Generic;
using DataStructures.Lists;
using Xunit;

namespace UnitTest.DataStructuresTests
{
public static class SkipListTest
{
[Fact]
public static void DoTest()
public static void AddOneElement()
{
var skipList = new SkipList<int>();

for (int i = 100; i >= 50; --i)
skipList.Add(i);
skipList.Add(10);

for (int i = 0; i <= 35; ++i)
skipList.Add(i);
Assert.True(skipList.Count == 1);
Assert.Contains(10, skipList);
}

for (int i = -15; i <= 0; ++i)
skipList.Add(i);
[Fact]
public static void AddBatchOfElements()
{
var skipList = new SkipList<int>();

for (int i = -15; i >= -35; --i)
for (int i = 100; i > 50; --i)
{
skipList.Add(i);
}

Assert.True(skipList.Count == 124);
Assert.True(skipList.Count == 50);
for (int i = 100; i > 50; --i)
{
Assert.Contains(i, skipList);
}
}

skipList.Clear();
[Fact]
public static void AddThreeElementsRemoveOneElement()
{
var skipList = new SkipList<int>();

skipList.Add(1);
skipList.Add(2);
skipList.Add(3);
skipList.Remove(2);

Assert.True(skipList.Count == 2);
Assert.Contains(1, skipList);
Assert.Contains(3, skipList);
Assert.DoesNotContain(2, skipList);
}

for (int i = 100; i >= 0; --i)
[Fact]
public static void AddAndRemoveBatchOfElements()
{
var skipList = new SkipList<int>();

for (int i = 100; i > 50; --i)
{
skipList.Add(i);
}

for (int i = 100; i > 50; --i)
{
skipList.Remove(i);
}

Assert.True(skipList.Count == 0);
for (int i = 100; i > 50; --i)
{
Assert.DoesNotContain(i, skipList);
}
}

[Fact]
public static void ClearList()
{
var skipList = new SkipList<int>();

skipList.Add(1);
skipList.Add(2);
skipList.Add(3);
skipList.Clear();

Assert.True(skipList.Count == 101);
Assert.True(skipList.Count == 0);
Assert.True(skipList.IsEmpty);
Assert.DoesNotContain(1, skipList);
Assert.DoesNotContain(2, skipList);
Assert.DoesNotContain(3, skipList);
}
}
}

0 comments on commit f769be0

Please sign in to comment.