Skip to content

Commit 836c125

Browse files
authored
Add Sorted List Data Structure (#238)
1 parent f0d0300 commit 836c125

File tree

3 files changed

+261
-2
lines changed

3 files changed

+261
-2
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using NUnit.Framework;
4+
5+
namespace DataStructures.Tests
6+
{
7+
[TestFixture]
8+
public class SortedListTests
9+
{
10+
[Test]
11+
public void Add_AddMultipleValues_SortingCorrectly(
12+
[Random(0, 1000, 100, Distinct = true)]
13+
int count)
14+
{
15+
var values = GetValues(count);
16+
var list = new SortedList<int>();
17+
18+
foreach (var value in values)
19+
{
20+
list.Add(value);
21+
}
22+
23+
CollectionAssert.AreEqual(values.OrderBy(i => i), list);
24+
}
25+
26+
[Test]
27+
public void Contains_PositiveArrayAdded_NegativeNumberAsked_FalseReturned(
28+
[Random(0, 200, 10, Distinct = true)] int count)
29+
{
30+
var values = GetValues(count);
31+
const int value = -1;
32+
33+
var list = new SortedList<int>();
34+
35+
foreach (var i in values)
36+
{
37+
list.Add(i);
38+
}
39+
40+
Assert.IsFalse(list.Contains(value));
41+
}
42+
43+
[Test]
44+
public void Contains_PositiveArrayAdded_ContainingValueAsked_TrueReturned(
45+
[Random(0, 200, 10, Distinct = true)] int count)
46+
{
47+
var values = GetValues(count);
48+
var value = values[TestContext.CurrentContext.Random.Next(count - 1)];
49+
50+
var list = new SortedList<int>();
51+
52+
foreach (var i in values)
53+
{
54+
list.Add(i);
55+
}
56+
57+
Assert.IsTrue(list.Contains(value));
58+
}
59+
60+
61+
[Test]
62+
public void Remove_PositiveArrayAdded_NegativeNumberAsked_FalseReturned(
63+
[Random(0, 200, 10, Distinct = true)] int count)
64+
{
65+
var values = GetValues(count);
66+
const int value = -1;
67+
68+
var list = new SortedList<int>();
69+
70+
foreach (var i in values)
71+
{
72+
list.Add(i);
73+
}
74+
75+
Assert.IsFalse(list.TryRemove(value));
76+
}
77+
78+
[Test]
79+
public void Remove_PositiveArrayAdded_ContainingValueAsked_TrueReturned(
80+
[Random(0, 200, 10, Distinct = true)] int count)
81+
{
82+
var values = GetValues(count);
83+
var value = values[TestContext.CurrentContext.Random.Next(count - 1)];
84+
85+
var list = new SortedList<int>();
86+
87+
foreach (var i in values)
88+
{
89+
list.Add(i);
90+
}
91+
92+
var expectingValues = values
93+
.OrderBy(i => i)
94+
.ToList();
95+
96+
expectingValues.Remove(value);
97+
98+
Assert.IsTrue(list.TryRemove(value));
99+
CollectionAssert.AreEqual(expectingValues, list);
100+
}
101+
102+
[Test]
103+
public void Clear_ArrayAdded_ListCleaned_ListIsEmpty(
104+
[Random(0, 20, 1, Distinct = true)] int count)
105+
{
106+
var values = GetValues(count);
107+
108+
var list = new SortedList<int>();
109+
110+
foreach (var i in values)
111+
{
112+
list.Add(i);
113+
}
114+
115+
list.Clear();
116+
117+
CollectionAssert.IsEmpty(list);
118+
}
119+
120+
private static List<int> GetValues(int count)
121+
=> Enumerable
122+
.Range(0, count)
123+
.Select(_ => TestContext.CurrentContext.Random.Next(1_000_000))
124+
.ToList();
125+
}
126+
}

DataStructures/SortedList.cs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
4+
namespace DataStructures
5+
{
6+
/// <summary>
7+
/// Implementation of SortedList using binary search.
8+
/// </summary>
9+
/// <typeparam name="T">Generic Type.</typeparam>
10+
public class SortedList<T> : IEnumerable<T>
11+
{
12+
private readonly IComparer<T> comparer;
13+
private readonly List<T> memory;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="SortedList{T}" /> class. Uses a Comparer.Default for type T.
17+
/// </summary>
18+
public SortedList()
19+
: this(Comparer<T>.Default)
20+
{
21+
}
22+
23+
/// <summary>
24+
/// Gets the number of elements containing in <see cref="SortedList{T}" />.
25+
/// </summary>
26+
public int Count => memory.Count;
27+
28+
/// <summary>
29+
/// Initializes a new instance of the <see cref="SortedList{T}" /> class.
30+
/// </summary>
31+
/// <param name="comparer">Comparer user for binary search.</param>
32+
public SortedList(IComparer<T> comparer)
33+
{
34+
memory = new List<T>();
35+
this.comparer = comparer;
36+
}
37+
38+
/// <summary>
39+
/// Adds new item to <see cref="SortedList{T}" /> instance, maintaining the order.
40+
/// </summary>
41+
/// <param name="item">An element to insert.</param>
42+
public void Add(T item)
43+
{
44+
var index = IndexFor(item, out _);
45+
memory.Insert(index, item);
46+
}
47+
48+
/// <summary>
49+
/// Gets an element of <see cref="SortedList{T}" /> at specified index.
50+
/// </summary>
51+
/// <param name="i">Index.</param>
52+
public T this[int i] => memory[i];
53+
54+
/// <summary>
55+
/// Removes all elements from <see cref="SortedList{T}" />.
56+
/// </summary>
57+
public void Clear()
58+
=> memory.Clear();
59+
60+
/// <summary>
61+
/// Indicates whether a <see cref="SortedList{T}" /> contains a certain element.
62+
/// </summary>
63+
/// <param name="item">An element to search.</param>
64+
/// <returns>true - <see cref="SortedList{T}" /> contains an element, otherwise - false.</returns>
65+
public bool Contains(T item)
66+
{
67+
_ = IndexFor(item, out var found);
68+
return found;
69+
}
70+
71+
/// <summary>
72+
/// Removes a certain element from <see cref="SortedList{T}" />.
73+
/// </summary>
74+
/// <param name="item">An element to remove.</param>
75+
/// <returns>true - element is found and removed, otherwise false.</returns>
76+
public bool TryRemove(T item)
77+
{
78+
var index = IndexFor(item, out var found);
79+
80+
if (found)
81+
{
82+
memory.RemoveAt(index);
83+
}
84+
85+
return found;
86+
}
87+
88+
/// <summary>
89+
/// Returns an enumerator that iterates through the <see cref="SortedList{T}" />.
90+
/// </summary>
91+
/// <returns>A Enumerator for the <see cref="SortedList{T}" />.</returns>
92+
public IEnumerator<T> GetEnumerator()
93+
=> memory.GetEnumerator();
94+
95+
/// <inheritdoc cref="IEnumerable.GetEnumerator"/>
96+
IEnumerator IEnumerable.GetEnumerator()
97+
=> GetEnumerator();
98+
99+
/// <summary>
100+
/// Binary search algorithm for finding element index in <see cref="SortedList{T}" />.
101+
/// </summary>
102+
/// <param name="item">Element.</param>
103+
/// <param name="found">Indicates whether the equal value was found in <see cref="SortedList{T}" />.</param>
104+
/// <returns>Index for the Element.</returns>
105+
private int IndexFor(T item, out bool found)
106+
{
107+
var left = 0;
108+
var right = memory.Count;
109+
110+
while (right - left > 0)
111+
{
112+
var mid = (left + right) / 2;
113+
114+
switch (comparer.Compare(item, memory[mid]))
115+
{
116+
case > 0:
117+
left = mid + 1;
118+
break;
119+
case < 0:
120+
right = mid;
121+
break;
122+
default:
123+
found = true;
124+
return mid;
125+
}
126+
}
127+
128+
found = false;
129+
return left;
130+
}
131+
}
132+
}

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
[![codecov](https://codecov.io/gh/TheAlgorithms/C-Sharp/branch/master/graph/badge.svg)](https://codecov.io/gh/TheAlgorithms/C-Sharp)
55
[![GuardRails badge](https://badges.guardrails.io/TheAlgorithms/C-Sharp.svg?token=84805208ba243f0931a74c5148883f894cbe9fd97fe54d64d6d0a89852067548)](https://dashboard.guardrails.io/default/gh/TheAlgorithms/C-Sharp)
66

7-
This repository contains algorithms and data structures implemented in C# for educational purposes.
7+
This repository contains algorithms and data structures implemented in C# for educational purposes.
88

9-
## Overview
9+
## Overview
1010

1111
* [Algorithms](./Algorithms)
1212
* [Data Compression](./Algorithms/DataCompression)
@@ -132,6 +132,7 @@ This repository contains algorithms and data structures implemented in C# for ed
132132
* [Doubly Linked List](./DataStructures/LinkedList/DoublyLinkedList/DoublyLinkedList.cs)
133133
* [Graph](./DataStructures/Graph)
134134
* [Directed Weighted Graph Via Adjacency Matrix](./DataStructures/Graph/DirectedWeightedGraph.cs)
135+
* [SortedList](./DataStructures/SortedList.cs)
135136

136137

137138
## Contributing

0 commit comments

Comments
 (0)