Skip to content

Commit f769be0

Browse files
committed
Fixed Issue aalhour#137 Items are not always added to a SkipList
1 parent 504140e commit f769be0

File tree

3 files changed

+97
-53
lines changed

3 files changed

+97
-53
lines changed

DataStructures/Lists/SkipList.cs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,6 @@ public class SkipList<T> : ICollection<T>, IEnumerable<T> where T : IComparable<
2828
private readonly int MaxLevel = 32;
2929
private readonly double Probability = 0.5;
3030

31-
32-
/// <summary>
33-
/// Private helper. Used in Add method.
34-
/// </summary>
35-
/// <returns></returns>
36-
private int _getNextLevel()
37-
{
38-
int lvl = 0;
39-
40-
while (_randomizer.NextDouble() < Probability && lvl <= _currentMaxLevel && lvl < MaxLevel)
41-
++lvl;
42-
43-
return lvl;
44-
}
45-
46-
4731
/// <summary>
4832
/// CONSTRUCTOR
4933
/// </summary>
@@ -94,12 +78,15 @@ public int Level
9478
/// <summary>
9579
/// Access elements by index
9680
/// </summary>
97-
public T this[int index]
81+
public T this[T item]
9882
{
9983
get
10084
{
101-
// TODO:
102-
throw new NotImplementedException();
85+
return Find(item, out var result) ? result : throw new KeyNotFoundException();
86+
}
87+
set
88+
{
89+
Add(item);
10390
}
10491
}
10592

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

122-
current = current.Forwards[0];
123-
124109
// Get the next node level, and update list level if required.
125110
int lvl = _getNextLevel();
126111
if (lvl > _currentMaxLevel)
@@ -150,8 +135,7 @@ public void Add(T item)
150135
/// </summary>
151136
public bool Remove(T item)
152137
{
153-
T deleted;
154-
return Remove(item, out deleted);
138+
return Remove(item, out var _);
155139
}
156140

157141
/// <summary>
@@ -185,8 +169,12 @@ public bool Remove(T item, out T deleted)
185169
// We know that the node is in the list.
186170
// Unlink it from the levels where it exists.
187171
for (int i = 0; i < _currentMaxLevel; ++i)
172+
{
188173
if (toBeUpdated[i].Forwards[i] == current)
174+
{
189175
toBeUpdated[i].Forwards[i] = current.Forwards[i];
176+
}
177+
}
190178

191179
// Decrement the count
192180
--_count;
@@ -367,6 +355,19 @@ public void Clear()
367355
}
368356
#endregion
369357

358+
/// <summary>
359+
/// Private helper. Used in Add method.
360+
/// </summary>
361+
/// <returns></returns>
362+
private int _getNextLevel()
363+
{
364+
int lvl = 1;
365+
366+
while (_randomizer.NextDouble() < Probability && lvl <= _currentMaxLevel && lvl < MaxLevel)
367+
++lvl;
368+
369+
return lvl;
370+
}
370371
}
371372

372373
}

DataStructures/Lists/SkipListNode.cs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ namespace DataStructures.Lists
44
{
55
public class SkipListNode<T> : IComparable<SkipListNode<T>> where T : IComparable<T>
66
{
7-
/// <summary>
8-
/// Instance variables
9-
/// </summary>
10-
private T _value;
11-
private SkipListNode<T>[] _forwards;
12-
137
/// <summary>
148
/// CONSTRUCTORS
159
/// </summary>
@@ -25,20 +19,12 @@ public SkipListNode(T value, int level)
2519
/// <summary>
2620
/// Get and set node's value
2721
/// </summary>
28-
public virtual T Value
29-
{
30-
get { return this._value; }
31-
private set { this._value = value; }
32-
}
22+
public virtual T Value { get; private set; }
3323

3424
/// <summary>
3525
/// Get and set node's forwards links
3626
/// </summary>
37-
public virtual SkipListNode<T>[] Forwards
38-
{
39-
get { return this._forwards; }
40-
private set { this._forwards = value; }
41-
}
27+
public virtual SkipListNode<T>[] Forwards { get; private set; }
4228

4329
/// <summary>
4430
/// Return level of node.
@@ -55,7 +41,7 @@ public int CompareTo(SkipListNode<T> other)
5541
{
5642
if (other == null)
5743
return -1;
58-
44+
5945
return this.Value.CompareTo(other.Value);
6046
}
6147
}
Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,92 @@
1-
using DataStructures.Lists;
1+
using System.Collections.Generic;
2+
using DataStructures.Lists;
23
using Xunit;
34

45
namespace UnitTest.DataStructuresTests
56
{
67
public static class SkipListTest
78
{
89
[Fact]
9-
public static void DoTest()
10+
public static void AddOneElement()
1011
{
1112
var skipList = new SkipList<int>();
1213

13-
for (int i = 100; i >= 50; --i)
14-
skipList.Add(i);
14+
skipList.Add(10);
1515

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

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

22-
for (int i = -15; i >= -35; --i)
25+
for (int i = 100; i > 50; --i)
26+
{
2327
skipList.Add(i);
28+
}
2429

25-
Assert.True(skipList.Count == 124);
30+
Assert.True(skipList.Count == 50);
31+
for (int i = 100; i > 50; --i)
32+
{
33+
Assert.Contains(i, skipList);
34+
}
35+
}
2636

27-
skipList.Clear();
37+
[Fact]
38+
public static void AddThreeElementsRemoveOneElement()
39+
{
40+
var skipList = new SkipList<int>();
41+
42+
skipList.Add(1);
43+
skipList.Add(2);
44+
skipList.Add(3);
45+
skipList.Remove(2);
46+
47+
Assert.True(skipList.Count == 2);
48+
Assert.Contains(1, skipList);
49+
Assert.Contains(3, skipList);
50+
Assert.DoesNotContain(2, skipList);
51+
}
2852

29-
for (int i = 100; i >= 0; --i)
53+
[Fact]
54+
public static void AddAndRemoveBatchOfElements()
55+
{
56+
var skipList = new SkipList<int>();
57+
58+
for (int i = 100; i > 50; --i)
59+
{
3060
skipList.Add(i);
61+
}
62+
63+
for (int i = 100; i > 50; --i)
64+
{
65+
skipList.Remove(i);
66+
}
67+
68+
Assert.True(skipList.Count == 0);
69+
for (int i = 100; i > 50; --i)
70+
{
71+
Assert.DoesNotContain(i, skipList);
72+
}
73+
}
74+
75+
[Fact]
76+
public static void ClearList()
77+
{
78+
var skipList = new SkipList<int>();
79+
80+
skipList.Add(1);
81+
skipList.Add(2);
82+
skipList.Add(3);
83+
skipList.Clear();
3184

32-
Assert.True(skipList.Count == 101);
85+
Assert.True(skipList.Count == 0);
86+
Assert.True(skipList.IsEmpty);
87+
Assert.DoesNotContain(1, skipList);
88+
Assert.DoesNotContain(2, skipList);
89+
Assert.DoesNotContain(3, skipList);
3390
}
3491
}
3592
}

0 commit comments

Comments
 (0)