Skip to content

Commit 30b7a9d

Browse files
committed
Use HeapSort and IEnumerator
1 parent ead0062 commit 30b7a9d

File tree

1 file changed

+66
-100
lines changed

1 file changed

+66
-100
lines changed

Algorithms/Search/BinarySearcher.cs

Lines changed: 66 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,126 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
3-
4+
using Algorithms.Sorting;
45

56
namespace Algorithms.Search
67
{
7-
public static class BinarySearcher
8+
public class BinarySearcher<T> : IEnumerator<T>
89
{
910

11+
private readonly IList<T> _collection;
12+
private readonly Comparer<T> _comparer;
13+
14+
private int _currentItemIndex;
15+
private int _leftIndex;
16+
private int _rightIndex;
1017

1118
/// <summary>
12-
/// Apply Binary Search in a list.
19+
/// The value of the current item
1320
/// </summary>
14-
/// <typeparam name="T">Data type of items</typeparam>
15-
/// <param name="collection">A list of items</param>
16-
/// <param name="item">The item we search for</param>
17-
/// <returns>If item found, its' index, -1 otherwise</returns>
18-
public static int BinarySearch<T>(IList<T> collection, T item)
19-
{
20-
if (collection == null)
21+
public T Current {
22+
23+
get
2124
{
22-
throw new NullReferenceException("List is null");
25+
return _collection[_currentItemIndex];
2326
}
2427

25-
IList<T> sCollection = MergeSort<T>(collection);
26-
int itemIndex = sCollection.InternalBinarySearch(0, sCollection.Count - 1, item);
27-
return itemIndex;
2828
}
2929

3030

31+
object IEnumerator.Current => Current;
32+
3133
/// <summary>
32-
/// Apply MerseSort algorithm in a list.
34+
/// Class constructor
3335
/// </summary>
34-
/// <typeparam name="T">Data type of items</typeparam>
35-
/// <param name="collection">A list of items</param>
36-
/// <returns>Given list in ascending order</returns>
37-
public static IList<T> MergeSort<T>(IList<T> collection)
36+
/// <param name="collection">A list</param>
37+
/// <param name="comparer">A comparer</param>
38+
public BinarySearcher(IList<T> collection, Comparer<T> comparer)
3839
{
39-
int mid = collection.Count / 2;
40-
IList<T> leftList;
41-
IList<T> rightList;
42-
43-
if (collection.Count < 2)
40+
if (collection == null)
4441
{
45-
return collection;
46-
42+
throw new NullReferenceException("List is null");
4743
}
4844

49-
leftList = GetCopyOfList(collection, 0, mid - 1);
50-
rightList = GetCopyOfList(collection, mid, collection.Count - 1);
51-
52-
leftList = MergeSort<T>(leftList);
53-
rightList = MergeSort<T>(rightList);
54-
55-
return InternalMerge<T>(leftList, rightList);
45+
this._collection = collection;
46+
this._comparer = comparer;
47+
5648
}
5749

58-
50+
5951
/// <summary>
60-
/// Merge two lists in ascending order.
52+
/// Apply Binary Search in a list.
6153
/// </summary>
62-
/// <typeparam name="T">Data type of items</typeparam>
63-
/// <param name="leftCollection">The first list of items</param>
64-
/// <param name="rightCollection">The second list of items</param>
65-
/// <returns>Merged list in ascending order</returns>
66-
private static IList<T> InternalMerge<T>(IList<T> leftCollection, IList<T> rightCollection)
54+
/// <param name="item">The item we search for</param>
55+
/// <returns>If item found, its' index, -1 otherwise</returns>
56+
public int BinarySearch(T item)
6757
{
68-
int i = 0;
69-
int j = 0;
70-
71-
IList<T> tmp = new List<T>();
72-
Comparer<T> comparer = Comparer<T>.Default;
73-
74-
while (i < leftCollection.Count && j < rightCollection.Count)
75-
{
76-
if (comparer.Compare(leftCollection[i], rightCollection[j]) <= 0)
77-
{
78-
tmp.Add(leftCollection[i++]);
79-
}
80-
else
81-
{
82-
tmp.Add(rightCollection[j++]);
83-
}
84-
}
85-
86-
//Copy the remaining items of left list
87-
while(i < leftCollection.Count)
88-
{
89-
tmp.Add(leftCollection[i++]);
90-
}
91-
92-
//Copy the remaining items of right list
93-
while (j < rightCollection.Count)
94-
{
95-
tmp.Add(rightCollection[j++]);
96-
}
97-
98-
return tmp;
58+
_currentItemIndex = -1;
59+
_leftIndex = 0;
60+
_rightIndex = _collection.Count - 1;
61+
HeapSorter.HeapSort(_collection);
62+
InternalBinarySearch(item);
63+
return _currentItemIndex;
9964
}
10065

10166

10267
/// <summary>
10368
/// An implementation of binary search algorithm.
10469
/// </summary>
105-
/// <typeparam name="T">Data type of items</typeparam>
106-
/// <param name="collection">A list of items</param>
107-
/// <param name="left">The far left index of the list</param>
108-
/// <param name="right">The far right index of the list</param>
10970
/// <param name="item">The item we search for</param>
110-
/// <returns>If found, the index of the item, otherwise -1</returns>
111-
private static int InternalBinarySearch<T>(this IList<T> collection, int left, int right, T item)
71+
/// <returns></returns>
72+
private void InternalBinarySearch(T item)
11273
{
113-
int mid = left + (right - left) / 2;
114-
Comparer<T> comparer = Comparer<T>.Default;
115-
116-
if (left <= right)
74+
bool found = false;
75+
76+
while (MoveNext() && !found)
11777
{
118-
if (comparer.Compare(item,collection[mid]) < 0)
78+
if (_comparer.Compare(item, Current) < 0)
11979
{
120-
return collection.InternalBinarySearch<T>(left, mid - 1, item);
80+
_rightIndex = _currentItemIndex - 1;
12181
}
122-
else if (comparer.Compare(item, collection[mid]) > 0)
82+
else if (_comparer.Compare(item, Current) > 0)
12383
{
124-
return collection.InternalBinarySearch<T>(mid + 1, right, item);
84+
_leftIndex = _currentItemIndex + 1;
12585
}
12686
else
12787
{
128-
return mid;
88+
found = true;
12989
}
13090
}
131-
else
91+
92+
if (!found)
13293
{
133-
return -1;
94+
this.Reset();
13495
}
13596

13697
}
13798

138-
13999
/// <summary>
140-
/// Copies a range of a list to another list
100+
/// An implementation of IEnumerator's MoveNext method.
141101
/// </summary>
142-
/// <typeparam name="T">Data type of items</typeparam>
143-
/// <param name="list">A list of items</param>
144-
/// <param name="left">Starting index of the range</param>
145-
/// <param name="right">The last index of the range</param>
146-
/// <returns>A copy of the given list within the given range</returns>
147-
private static IList<T> GetCopyOfList<T>(IList<T> list, int left, int right)
102+
/// <returns>true if iteration can proceed to the next item, false otherwise</returns>
103+
public bool MoveNext()
148104
{
149-
IList<T> copyList = new List<T>();
105+
_currentItemIndex = this._leftIndex + (this._rightIndex - this._leftIndex) / 2;
150106

151-
for (int i = left; i <= right; i++)
107+
if (_leftIndex <= _rightIndex)
108+
{
109+
return true;
110+
}
111+
else
152112
{
153-
copyList.Add(list[i]);
113+
return false;
154114
}
155115

156-
return copyList;
157116
}
117+
118+
119+
public void Reset(){ this._currentItemIndex = -1; }
120+
121+
122+
public void Dispose(){}
123+
158124
}
159125

160126
}

0 commit comments

Comments
 (0)