From 6731d2b015a22f5b7f8edda2a332000ca3a0b628 Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 5 May 2023 23:18:39 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SkipList/SkipList/Program.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 SkipList/SkipList/Program.cs diff --git a/SkipList/SkipList/Program.cs b/SkipList/SkipList/Program.cs new file mode 100644 index 0000000..b0e783c --- /dev/null +++ b/SkipList/SkipList/Program.cs @@ -0,0 +1,17 @@ +namespace ListWithOmissions; + +class Program +{ + public static void Main(string[] args) + { + var list = new ListWithOmissions(); + list.Add(1); + list.Add(2); + list.Add(3); + var listForCheck = new List { 1, 2, 3 }; + int i = 0; + foreach (var item in list) + { + } + } +} \ No newline at end of file From 813f54d1c4158888c1d3c386845bf5647e400c54 Mon Sep 17 00:00:00 2001 From: Artem Date: Fri, 5 May 2023 23:25:36 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9,=20=D0=BD=D0=BE=20=D0=BD=D0=B5=D0=BE=D1=82?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA=20?= =?UTF-8?q?=D1=81=20=D0=BF=D1=80=D0=BE=D0=BF=D1=83=D1=81=D0=BA=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SkipList/SkipList.sln | 25 ++ SkipList/SkipList/IncorrectIndexException.cs | 3 + SkipList/SkipList/IncorrectMethodException.cs | 3 + SkipList/SkipList/Program.cs | 2 +- SkipList/SkipList/SkipList.cs | 421 ++++++++++++++++++ SkipList/SkipList/SkipList.csproj | 10 + SkipList/TestsForSkipList/TestsForSkipList.cs | 32 ++ .../TestsForSkipList/TestsForSkipList.csproj | 19 + SkipList/TestsForSkipList/Usings.cs | 1 + 9 files changed, 515 insertions(+), 1 deletion(-) create mode 100644 SkipList/SkipList.sln create mode 100644 SkipList/SkipList/IncorrectIndexException.cs create mode 100644 SkipList/SkipList/IncorrectMethodException.cs create mode 100644 SkipList/SkipList/SkipList.cs create mode 100644 SkipList/SkipList/SkipList.csproj create mode 100644 SkipList/TestsForSkipList/TestsForSkipList.cs create mode 100644 SkipList/TestsForSkipList/TestsForSkipList.csproj create mode 100644 SkipList/TestsForSkipList/Usings.cs diff --git a/SkipList/SkipList.sln b/SkipList/SkipList.sln new file mode 100644 index 0000000..baed356 --- /dev/null +++ b/SkipList/SkipList.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33403.182 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkipList", "SkipList\SkipList.csproj", "{4E18C267-E75F-45DB-B932-31593D09697E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4E18C267-E75F-45DB-B932-31593D09697E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E18C267-E75F-45DB-B932-31593D09697E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E18C267-E75F-45DB-B932-31593D09697E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E18C267-E75F-45DB-B932-31593D09697E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9FBA4961-6031-4E7B-87CC-E0F7812D9517} + EndGlobalSection +EndGlobal diff --git a/SkipList/SkipList/IncorrectIndexException.cs b/SkipList/SkipList/IncorrectIndexException.cs new file mode 100644 index 0000000..ac7df67 --- /dev/null +++ b/SkipList/SkipList/IncorrectIndexException.cs @@ -0,0 +1,3 @@ +namespace SkipList; + +internal class IncorrectIndexException : Exception {} \ No newline at end of file diff --git a/SkipList/SkipList/IncorrectMethodException.cs b/SkipList/SkipList/IncorrectMethodException.cs new file mode 100644 index 0000000..0d462e5 --- /dev/null +++ b/SkipList/SkipList/IncorrectMethodException.cs @@ -0,0 +1,3 @@ +namespace SkipList; + +internal class IncorrectMethodException : Exception {} \ No newline at end of file diff --git a/SkipList/SkipList/Program.cs b/SkipList/SkipList/Program.cs index b0e783c..084ef9d 100644 --- a/SkipList/SkipList/Program.cs +++ b/SkipList/SkipList/Program.cs @@ -1,4 +1,4 @@ -namespace ListWithOmissions; +namespace SkipList; class Program { diff --git a/SkipList/SkipList/SkipList.cs b/SkipList/SkipList/SkipList.cs new file mode 100644 index 0000000..a8b1c9c --- /dev/null +++ b/SkipList/SkipList/SkipList.cs @@ -0,0 +1,421 @@ +namespace SkipList; + +using System.Collections; + +public class SkipList : IList where T : IComparable +{ + private class List + { + public ElementList? element; + } + + private class MainList + { + public MainList? nextList; + public List? list; + public int size; + } + + private MainList? MajorList; + + public void Add(T item) + { + if (MajorList == null) + { + MajorList = new MainList(); + MajorList.list = new List(); + MajorList.list.element = new ElementList(0, item, 0); + MajorList.size = 1; + return; + } + + if (MajorList.list == null || MajorList.list.element == null) + { + throw new NullReferenceException(); + } + + var walker = MajorList.list.element; + var stack = new Stack(); + + ++MajorList.size; + + while (walker != null) + { + if (walker.next == null) + { + if (walker.level == 0) + { + var copy = walker.next; + walker.next = new ElementList(walker.position + 1, item, 0); + walker.next.next = copy; + var randomNumber = new Random(); + int position = 1; + var previousLevelItem = walker.next; + while (randomNumber.Next(0, 2) == 0) + { + if (stack.Count > 0) + { + var walkerFromStack = stack.Pop(); + var copyForStack = walkerFromStack.next; + walkerFromStack.next = new ElementList(walker.position + 1, item, position); + walkerFromStack.next.next = copyForStack; + walkerFromStack.next.down = previousLevelItem; + previousLevelItem = walkerFromStack.next; + position++; + } + else + { + var newList = new List(); + newList.element = new ElementList(0, MajorList.list.element.value, MajorList.list.element.level + 1); + newList.element.next = new ElementList(walker.position + 1, item, position); + newList.element.next.down = previousLevelItem; + newList.element.down = MajorList.list.element; + previousLevelItem = newList.element.next; + var copyMajorList = MajorList; + MajorList = new MainList(); + MajorList.list = newList; + MajorList.nextList = copyMajorList; + MajorList.size = copyMajorList.size; + position++; + } + } + return; + } + else + { + stack.Push(walker); + walker = walker.down; + } + } + + if (walker != null && walker.next != null && item.CompareTo(walker.next.value) >= 0) + { + walker = walker.next; + } + else if (walker != null && walker.next != null && item.CompareTo(walker.next.value) < 0) + { + walker = walker.down; + } + } + } + + private T FindElementByIndex(int index) + { + if (MajorList == null || MajorList.list == null || MajorList.list.element == null) + { + throw new NullReferenceException(); + } + + var walker = MajorList.list.element; + while (walker != null) + { + if (walker != null && walker.position == index) + { + return walker.value; + } + if (walker != null && walker.next != null && index >= walker.next.position) + { + walker = walker.next; + } + else if (walker != null && walker.next != null && index <= walker.next.position) + { + walker = walker.down; + } + } + throw new IncorrectIndexException(); + } + + public T this[int index] { get => FindElementByIndex(index); set => throw new NotImplementedException(); } + + public int Count => MajorList == null ? throw new NullReferenceException() : MajorList.size; + + public bool IsReadOnly => false; + + + public void Clear() + { + MajorList = null; + } + + public bool Contains(T item) + { + if (MajorList == null || MajorList.list == null || MajorList.list.element == null) + { + return false; + } + + var walker = MajorList.list.element; + while (walker != null) + { + if (walker.level == 0) + { + return item.CompareTo(walker.value) == 0; + } + if (walker != null && walker.next != null && item.CompareTo(walker.next.value) >= 0) + { + walker = walker.next; + } + else if (walker != null && walker.next != null && item.CompareTo(walker.next.value) < 0) + { + walker = walker.down; + } + } + return false; + } + + public void CopyTo(T[] array, int arrayIndex) + { + if (MajorList == null || MajorList.list == null || MajorList.list.element == null) + { + throw new NullReferenceException(); + } + var walker = MajorList; + while (walker.nextList != null) + { + walker = walker.nextList; + } + + if (walker.list == null || walker.list.element == null) + { + throw new NullReferenceException(); + } + + var walkerForArray = walker.list.element; + var listArray = new List(array); + + while (walkerForArray != null) + { + listArray.Add(walkerForArray.value); + } + + array = listArray.ToArray(); + } + + private class ListEnum : IEnumerator + { + private T[] listEnum; + + int position = -1; + + public ListEnum(T[] list) + { + listEnum = list; + } + + public object Current + { + get + { + try + { + return listEnum[position]; + } + catch (IndexOutOfRangeException) + { + throw new IncorrectIndexException(); + } + } + + } + + T IEnumerator.Current + { + get + { + return (T)Current; + } + } + + public void Dispose() + { + GC.SuppressFinalize(this); + } + + public bool MoveNext() + { + position++; + return (position < listEnum.Length); + } + + public void Reset() + { + position = -1; + } + } + + public IEnumerator GetEnumerator() + { + if (MajorList == null || MajorList.list == null) + { + throw new NullReferenceException(); + } + var walker = MajorList; + while (walker.nextList != null) + { + walker = walker.nextList; + } + var arrayValue = new T[MajorList.size]; + + if (walker.list == null) + { + throw new NullReferenceException(); + } + + var walkerList = walker.list.element; + if (walkerList == null) + { + throw new NullReferenceException(); + } + int i = 0; + while (walkerList != null) + { + arrayValue[i] = walkerList.value; + ++i; + walkerList = walkerList.next; + } + return new ListEnum(arrayValue); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return (IEnumerator)GetEnumerator(); + } + + public int IndexOf(T item) + { + if (MajorList == null || MajorList.list == null || MajorList.list.element == null) + { + throw new NullReferenceException(); + } + + var walker = MajorList.list.element; + while (walker != null) + { + if (walker.level == 0) + { + return item.CompareTo(walker.value) == 0 ? walker.position : -1; + } + if (walker != null && walker.next != null && item.CompareTo(walker.next.value) >= 0) + { + walker = walker.next; + } + else if (walker != null && walker.next != null && item.CompareTo(walker.next.value) < 0) + { + walker = walker.down; + } + } + return -1; + } + + public void Insert(int index, T item) + { + throw new IncorrectMethodException(); + } + + public bool Remove(T item) + { + if (MajorList == null || MajorList.list == null || MajorList.list.element == null) + { + throw new NullReferenceException(); + } + var walker = MajorList.list.element; + var previousWalker = walker; + var mainLevel = MajorList; + while (walker != null) + { + if (item.CompareTo(walker.value) == 0) + { + var copy = walker.next; + if (previousWalker == null) + { + throw new NullReferenceException(); + } + previousWalker.next = copy; + walker = walker.down; + previousWalker = walker; + if (walker == null) + { + return true; + } + } + + if (walker != null && walker.next != null && item.CompareTo(walker.next.value) >= 0) + { + previousWalker = walker; + walker = walker.next; + } + else if (walker != null && walker.next != null && item.CompareTo(walker.next.value) < 0) + { + previousWalker = walker; + if (mainLevel == null) + { + throw new NullReferenceException(); + } + mainLevel = mainLevel.nextList; + walker = walker.down; + } + } + return false; + } + + public void RemoveAt(int index) + { + if (MajorList == null || MajorList.list == null || MajorList.list.element == null) + { + throw new NullReferenceException(); + } + var walker = MajorList.list.element; + var previousWalker = walker; + var mainLevel = MajorList; + while (walker != null) + { + if (index == walker.position) + { + var copy = walker.next; + if (previousWalker == null) + { + throw new NullReferenceException(); + } + previousWalker.next = copy; + walker = walker.down; + previousWalker = walker; + } + + if (walker != null && walker.next != null && walker.next.position <= index) + { + previousWalker = walker; + walker = walker.next; + } + else if (walker != null && walker.next != null && index < walker.next.position) + { + previousWalker = walker; + if (mainLevel == null) + { + throw new NullReferenceException(); + } + mainLevel = mainLevel.nextList; + walker = walker.down; + } + } + } + + private class ElementList + { + public ElementList(int index, T item, int standart) + { + value = item; + position = index; + level = standart; + } + + public ElementList? next { get; set; } + + public ElementList? down { get; set; } + + public T? value { get; set; } + + public int position { get; set; } + + public int level { get; set; } + } +} diff --git a/SkipList/SkipList/SkipList.csproj b/SkipList/SkipList/SkipList.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/SkipList/SkipList/SkipList.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/SkipList/TestsForSkipList/TestsForSkipList.cs b/SkipList/TestsForSkipList/TestsForSkipList.cs new file mode 100644 index 0000000..058ca51 --- /dev/null +++ b/SkipList/TestsForSkipList/TestsForSkipList.cs @@ -0,0 +1,32 @@ +namespace TestsForSkipList; + +using SkipList; + +public class Tests +{ + SkipList list; + [SetUp] + public void Setup() + { + list = new SkipList(); + } + + [Test] + public void ListWithOmissionsShouldCorrectAdd() + { + list.Add(1); + list.Add(2); + list.Add(3); + var listForCheck = new List { 1, 2, 3 }; + int i = 0; + foreach (var item in list) + { + if (item != listForCheck[i]) + { + Assert.Fail(); + } + ++i; + } + Assert.Pass(); + } +} \ No newline at end of file diff --git a/SkipList/TestsForSkipList/TestsForSkipList.csproj b/SkipList/TestsForSkipList/TestsForSkipList.csproj new file mode 100644 index 0000000..cbb7690 --- /dev/null +++ b/SkipList/TestsForSkipList/TestsForSkipList.csproj @@ -0,0 +1,19 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + + diff --git a/SkipList/TestsForSkipList/Usings.cs b/SkipList/TestsForSkipList/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/SkipList/TestsForSkipList/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file From b101fb81155352e7932de0a7a442d609e761f3f1 Mon Sep 17 00:00:00 2001 From: Artem Date: Sat, 6 May 2023 18:36:31 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D1=8B=20+=20=D1=83?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SkipList/SkipList.sln | 6 ++ SkipList/SkipList/Program.cs | 2 +- SkipList/SkipList/SkipList.cs | 27 ++++++- SkipList/TestsForSkipList/TestsForSkipList.cs | 75 +++++++++++++++++++ .../TestsForSkipList/TestsForSkipList.csproj | 4 + 5 files changed, 111 insertions(+), 3 deletions(-) diff --git a/SkipList/SkipList.sln b/SkipList/SkipList.sln index baed356..74f7220 100644 --- a/SkipList/SkipList.sln +++ b/SkipList/SkipList.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.4.33403.182 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkipList", "SkipList\SkipList.csproj", "{4E18C267-E75F-45DB-B932-31593D09697E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsForSkipList", "TestsForSkipList\TestsForSkipList.csproj", "{6DA9CE59-BE2C-4893-8881-7D2BC3B808BD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {4E18C267-E75F-45DB-B932-31593D09697E}.Debug|Any CPU.Build.0 = Debug|Any CPU {4E18C267-E75F-45DB-B932-31593D09697E}.Release|Any CPU.ActiveCfg = Release|Any CPU {4E18C267-E75F-45DB-B932-31593D09697E}.Release|Any CPU.Build.0 = Release|Any CPU + {6DA9CE59-BE2C-4893-8881-7D2BC3B808BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6DA9CE59-BE2C-4893-8881-7D2BC3B808BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6DA9CE59-BE2C-4893-8881-7D2BC3B808BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6DA9CE59-BE2C-4893-8881-7D2BC3B808BD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SkipList/SkipList/Program.cs b/SkipList/SkipList/Program.cs index 084ef9d..5bd3922 100644 --- a/SkipList/SkipList/Program.cs +++ b/SkipList/SkipList/Program.cs @@ -4,7 +4,7 @@ class Program { public static void Main(string[] args) { - var list = new ListWithOmissions(); + var list = new SkipList(); list.Add(1); list.Add(2); list.Add(3); diff --git a/SkipList/SkipList/SkipList.cs b/SkipList/SkipList/SkipList.cs index a8b1c9c..82c1103 100644 --- a/SkipList/SkipList/SkipList.cs +++ b/SkipList/SkipList/SkipList.cs @@ -141,7 +141,7 @@ public bool Contains(T item) { if (MajorList == null || MajorList.list == null || MajorList.list.element == null) { - return false; + throw new NullReferenceException(); } var walker = MajorList.list.element; @@ -149,6 +149,10 @@ public bool Contains(T item) { if (walker.level == 0) { + while (walker.next != null && item.CompareTo(walker.next.value) >= 0) + { + walker = walker.next; + } return item.CompareTo(walker.value) == 0; } if (walker != null && walker.next != null && item.CompareTo(walker.next.value) >= 0) @@ -181,11 +185,30 @@ public void CopyTo(T[] array, int arrayIndex) } var walkerForArray = walker.list.element; - var listArray = new List(array); + var listArray = new List(); while (walkerForArray != null) { listArray.Add(walkerForArray.value); + walkerForArray = walkerForArray.next; + } + + int sizeListArray = listArray.Count; + if (arrayIndex > array.Length) + { + throw new IndexOutOfRangeException(); + } + + int j = 0; + while (j < sizeListArray) + { + if (arrayIndex >= array.Length) + { + Array.Resize(ref array, array.Length + 1); + } + array[arrayIndex] = listArray[j]; + ++arrayIndex; + ++j; } array = listArray.ToArray(); diff --git a/SkipList/TestsForSkipList/TestsForSkipList.cs b/SkipList/TestsForSkipList/TestsForSkipList.cs index 058ca51..2b28b49 100644 --- a/SkipList/TestsForSkipList/TestsForSkipList.cs +++ b/SkipList/TestsForSkipList/TestsForSkipList.cs @@ -1,6 +1,8 @@ namespace TestsForSkipList; using SkipList; +using System; +using static System.Runtime.InteropServices.JavaScript.JSType; public class Tests { @@ -29,4 +31,77 @@ public void ListWithOmissionsShouldCorrectAdd() } Assert.Pass(); } + + [Test] + public void AnUninitializedListShouldThrowExceptionWhenTryingToGetSize() + { + Assert.Throws(() => list.Count()); + } + + [Test] + public void NullListShouldThrowExceptionThenWhenTryingToCopyValuesToAnArray() + { + var arrayCopy = new int[5]; + Assert.Throws(() => list.CopyTo(arrayCopy, 0)); + } + + [Test] + public void NullListShouldThrowExceptionThenWhenTryingToRemoveValue() + { + Assert.Throws(() => list.Remove(3)); + } + + [Test] + public void NullListShouldThrowExceptionThenWhenTryingToRemoveByIndexValue() + { + Assert.Throws(() => list.RemoveAt(3)); + } + + [Test] + public void NullListShouldThrowExceptionThenWhenTryingToUseMethodContains() + { + Assert.Throws(() => list.Contains(3)); + } + + [Test] + public void ListWithMethodContainsShouldWorkCorrectly() + { + list.Add(3); + list.Add(4); + list.Add(5); + Assert.True(list.Contains(4) && !list.Contains(7)); + } + + [Test] + public void ListWithMethodCopyToShouldWorkCorrectly() + { + list.Add(3); + list.Add(4); + list.Add(5); + var arrayToCopy = new int[3]; + var arrayCheck = new int[3]{3, 4, 5 }; + list.CopyTo(arrayToCopy, 0); + Assert.True(arrayToCopy.SequenceEqual(arrayCheck)); + } + + [Test] + public void ListWithMethodRemoveShouldWorkCorrectly() + { + list.Add(3); + list.Add(4); + list.Add(5); + list.Remove(4); + Assert.True(!list.Contains(4)); + } + + [Test] + public void ListWithMethodRemoveAtShouldWorkCorrectly() + { + list.Add(3); + list.Add(4); + list.Add(5); + list.Remove(4); + Assert.True(!list.Contains(4)); + } + } \ No newline at end of file diff --git a/SkipList/TestsForSkipList/TestsForSkipList.csproj b/SkipList/TestsForSkipList/TestsForSkipList.csproj index cbb7690..6f7a828 100644 --- a/SkipList/TestsForSkipList/TestsForSkipList.csproj +++ b/SkipList/TestsForSkipList/TestsForSkipList.csproj @@ -16,4 +16,8 @@ + + + + From 379a9a5e9f39e98c0a525fc74edd4e5aca5287f2 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 7 May 2023 19:46:02 +0300 Subject: [PATCH 4/4] =?UTF-8?q?+=D0=A2=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SkipList/SkipList/SkipList.cs | 97 +++++++++---------- SkipList/TestsForSkipList/TestsForSkipList.cs | 9 +- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/SkipList/SkipList/SkipList.cs b/SkipList/SkipList/SkipList.cs index 82c1103..e0380fa 100644 --- a/SkipList/SkipList/SkipList.cs +++ b/SkipList/SkipList/SkipList.cs @@ -24,7 +24,8 @@ public void Add(T item) { MajorList = new MainList(); MajorList.list = new List(); - MajorList.list.element = new ElementList(0, item, 0); + MajorList.list.element = new ElementList(-1, default(T), 0); + MajorList.list.element.next = new ElementList(0, item, 0); MajorList.size = 1; return; } @@ -66,7 +67,7 @@ public void Add(T item) else { var newList = new List(); - newList.element = new ElementList(0, MajorList.list.element.value, MajorList.list.element.level + 1); + newList.element = new ElementList(-1, default(T), MajorList.list.element.level + 1); newList.element.next = new ElementList(walker.position + 1, item, position); newList.element.next.down = previousLevelItem; newList.element.down = MajorList.list.element; @@ -159,8 +160,12 @@ public bool Contains(T item) { walker = walker.next; } - else if (walker != null && walker.next != null && item.CompareTo(walker.next.value) < 0) + else { + if (walker == null) + { + throw new NullReferenceException(); + } walker = walker.down; } } @@ -184,9 +189,15 @@ public void CopyTo(T[] array, int arrayIndex) throw new NullReferenceException(); } - var walkerForArray = walker.list.element; + + var walkerForArray = walker.list.element.next; var listArray = new List(); + if (walkerForArray == null) + { + throw new NullReferenceException(); + } + while (walkerForArray != null) { listArray.Add(walkerForArray.value); @@ -279,12 +290,12 @@ public IEnumerator GetEnumerator() } var arrayValue = new T[MajorList.size]; - if (walker.list == null) + if (walker.list == null || walker.list.element == null) { throw new NullReferenceException(); } - var walkerList = walker.list.element; + var walkerList = walker.list.element.next; if (walkerList == null) { throw new NullReferenceException(); @@ -335,7 +346,7 @@ public void Insert(int index, T item) throw new IncorrectMethodException(); } - public bool Remove(T item) + public bool RemoveByIndexOrItem(T item, int index, bool byIndex) { if (MajorList == null || MajorList.list == null || MajorList.list.element == null) { @@ -346,28 +357,43 @@ public bool Remove(T item) var mainLevel = MajorList; while (walker != null) { - if (item.CompareTo(walker.value) == 0) + if (!byIndex && item.CompareTo(walker.value) == 0 || byIndex && index == walker.position) { var copy = walker.next; + var copyCopy = copy; + + while (copyCopy != null) + { + --copyCopy.position; + copyCopy = copyCopy.next; + } + if (previousWalker == null) { throw new NullReferenceException(); } previousWalker.next = copy; walker = walker.down; - previousWalker = walker; + previousWalker = previousWalker.down; + while (previousWalker != null && previousWalker.next != null + && (item.CompareTo(previousWalker.next.value) != 0 && !byIndex + || byIndex && index != previousWalker.next.position)) + { + previousWalker = previousWalker.next; + } if (walker == null) { return true; } } - - if (walker != null && walker.next != null && item.CompareTo(walker.next.value) >= 0) + else if (walker != null && walker.next != null && + (item.CompareTo(walker.next.value) >= 0 && !byIndex + || index >= walker.next.position && byIndex)) { previousWalker = walker; walker = walker.next; } - else if (walker != null && walker.next != null && item.CompareTo(walker.next.value) < 0) + else { previousWalker = walker; if (mainLevel == null) @@ -375,51 +401,24 @@ public bool Remove(T item) throw new NullReferenceException(); } mainLevel = mainLevel.nextList; + if (walker == null) + { + throw new NullReferenceException(); + } walker = walker.down; } } return false; } - public void RemoveAt(int index) + public bool Remove(T item) { - if (MajorList == null || MajorList.list == null || MajorList.list.element == null) - { - throw new NullReferenceException(); - } - var walker = MajorList.list.element; - var previousWalker = walker; - var mainLevel = MajorList; - while (walker != null) - { - if (index == walker.position) - { - var copy = walker.next; - if (previousWalker == null) - { - throw new NullReferenceException(); - } - previousWalker.next = copy; - walker = walker.down; - previousWalker = walker; - } + return RemoveByIndexOrItem(item, 0, false); + } - if (walker != null && walker.next != null && walker.next.position <= index) - { - previousWalker = walker; - walker = walker.next; - } - else if (walker != null && walker.next != null && index < walker.next.position) - { - previousWalker = walker; - if (mainLevel == null) - { - throw new NullReferenceException(); - } - mainLevel = mainLevel.nextList; - walker = walker.down; - } - } + public void RemoveAt(int index) + { + RemoveByIndexOrItem(default(T), index, true); } private class ElementList diff --git a/SkipList/TestsForSkipList/TestsForSkipList.cs b/SkipList/TestsForSkipList/TestsForSkipList.cs index 2b28b49..4dbc768 100644 --- a/SkipList/TestsForSkipList/TestsForSkipList.cs +++ b/SkipList/TestsForSkipList/TestsForSkipList.cs @@ -63,6 +63,7 @@ public void NullListShouldThrowExceptionThenWhenTryingToUseMethodContains() Assert.Throws(() => list.Contains(3)); } + [Test] public void ListWithMethodContainsShouldWorkCorrectly() { @@ -71,7 +72,8 @@ public void ListWithMethodContainsShouldWorkCorrectly() list.Add(5); Assert.True(list.Contains(4) && !list.Contains(7)); } - + + [Test] public void ListWithMethodCopyToShouldWorkCorrectly() { @@ -83,7 +85,7 @@ public void ListWithMethodCopyToShouldWorkCorrectly() list.CopyTo(arrayToCopy, 0); Assert.True(arrayToCopy.SequenceEqual(arrayCheck)); } - + [Test] public void ListWithMethodRemoveShouldWorkCorrectly() { @@ -100,8 +102,7 @@ public void ListWithMethodRemoveAtShouldWorkCorrectly() list.Add(3); list.Add(4); list.Add(5); - list.Remove(4); + list.RemoveAt(1); Assert.True(!list.Contains(4)); } - } \ No newline at end of file