From 321e83881fa840d209c0ef2aa2a1a6c6878b8683 Mon Sep 17 00:00:00 2001 From: Gutsonok Date: Sat, 8 Aug 2020 23:38:05 +0500 Subject: [PATCH] Fix #140 Program crashes upon search for null in a SkipList --- DataStructures/Lists/SkipList.cs | 20 ++++++++++++++- UnitTest/DataStructuresTests/SkipListTest.cs | 27 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/DataStructures/Lists/SkipList.cs b/DataStructures/Lists/SkipList.cs index 4a990403..dbb57bc0 100644 --- a/DataStructures/Lists/SkipList.cs +++ b/DataStructures/Lists/SkipList.cs @@ -208,12 +208,31 @@ public bool Contains(T item) /// public bool Find(T item, out T result) { + result = default(T); + var current = _firstNode; + // If find null element then check first element after first node + if (item == null) + { + current = current.Forwards[0]; + return current != null && current.Value == null; + } + + // Skip null element (in first postion) if contain + if (!IsEmpty && current.Forwards[0].Value == null) + { + current = current.Forwards[0]; + } + // Walk after all the nodes that have values less than the node we are looking for for (int i = _currentMaxLevel - 1; i >= 0; --i) + { while (current.Forwards[i] != null && current.Forwards[i].Value.IsLessThan(item)) + { current = current.Forwards[i]; + } + } current = current.Forwards[0]; @@ -224,7 +243,6 @@ public bool Find(T item, out T result) return true; } - result = default(T); return false; } diff --git a/UnitTest/DataStructuresTests/SkipListTest.cs b/UnitTest/DataStructuresTests/SkipListTest.cs index 244700fb..cbbe3e15 100644 --- a/UnitTest/DataStructuresTests/SkipListTest.cs +++ b/UnitTest/DataStructuresTests/SkipListTest.cs @@ -1,5 +1,4 @@ -using System.Runtime.InteropServices.ComTypes; -using DataStructures.Lists; +using DataStructures.Lists; using Xunit; namespace UnitTest.DataStructuresTests @@ -16,6 +15,17 @@ public static void Initialization_ListIsEmpty() Assert.DoesNotContain(0, skipList); } + [Fact] + public static void InitializationWithReferencyTypeAsGeneric_ListIsEmpty() + { + var skipList = new SkipList(); + + Assert.True(skipList.Count == 0); + Assert.True(skipList.IsEmpty); + Assert.DoesNotContain(null, skipList); + Assert.DoesNotContain(string.Empty, skipList); + } + [Fact] public static void Add_NullElement_ListContainNullElement() { @@ -27,6 +37,19 @@ public static void Add_NullElement_ListContainNullElement() Assert.Contains(null, skipList); } + [Fact] + public static void Add_NullElementAfterNonNull_ListContainNullElement() + { + var skipList = new SkipList(); + + skipList.Add("1"); + skipList.Add(null); + + Assert.True(skipList.Count == 2); + Assert.Contains(null, skipList); + Assert.Contains("1", skipList); + } + [Theory] [InlineData(10)] [InlineData(-10)]