1
1
using System ;
2
+ using System . Collections ;
2
3
using System . Collections . Generic ;
3
-
4
+ using Algorithms . Sorting ;
4
5
5
6
namespace Algorithms . Search
6
7
{
7
- public static class BinarySearcher
8
+ public class BinarySearcher < T > : IEnumerator < T >
8
9
{
9
10
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 ;
10
17
11
18
/// <summary>
12
- /// Apply Binary Search in a list.
19
+ /// The value of the current item
13
20
/// </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
21
24
{
22
- throw new NullReferenceException ( "List is null" ) ;
25
+ return _collection [ _currentItemIndex ] ;
23
26
}
24
27
25
- IList < T > sCollection = MergeSort < T > ( collection ) ;
26
- int itemIndex = sCollection . InternalBinarySearch ( 0 , sCollection . Count - 1 , item ) ;
27
- return itemIndex ;
28
28
}
29
29
30
30
31
+ object IEnumerator . Current => Current ;
32
+
31
33
/// <summary>
32
- /// Apply MerseSort algorithm in a list.
34
+ /// Class constructor
33
35
/// </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 )
38
39
{
39
- int mid = collection . Count / 2 ;
40
- IList < T > leftList ;
41
- IList < T > rightList ;
42
-
43
- if ( collection . Count < 2 )
40
+ if ( collection == null )
44
41
{
45
- return collection ;
46
-
42
+ throw new NullReferenceException ( "List is null" ) ;
47
43
}
48
44
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
+
56
48
}
57
49
58
-
50
+
59
51
/// <summary>
60
- /// Merge two lists in ascending order .
52
+ /// Apply Binary Search in a list .
61
53
/// </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 )
67
57
{
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 ;
99
64
}
100
65
101
66
102
67
/// <summary>
103
68
/// An implementation of binary search algorithm.
104
69
/// </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>
109
70
/// <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 )
112
73
{
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 )
117
77
{
118
- if ( comparer . Compare ( item , collection [ mid ] ) < 0 )
78
+ if ( _comparer . Compare ( item , Current ) < 0 )
119
79
{
120
- return collection . InternalBinarySearch < T > ( left , mid - 1 , item ) ;
80
+ _rightIndex = _currentItemIndex - 1 ;
121
81
}
122
- else if ( comparer . Compare ( item , collection [ mid ] ) > 0 )
82
+ else if ( _comparer . Compare ( item , Current ) > 0 )
123
83
{
124
- return collection . InternalBinarySearch < T > ( mid + 1 , right , item ) ;
84
+ _leftIndex = _currentItemIndex + 1 ;
125
85
}
126
86
else
127
87
{
128
- return mid ;
88
+ found = true ;
129
89
}
130
90
}
131
- else
91
+
92
+ if ( ! found )
132
93
{
133
- return - 1 ;
94
+ this . Reset ( ) ;
134
95
}
135
96
136
97
}
137
98
138
-
139
99
/// <summary>
140
- /// Copies a range of a list to another list
100
+ /// An implementation of IEnumerator's MoveNext method.
141
101
/// </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 ( )
148
104
{
149
- IList < T > copyList = new List < T > ( ) ;
105
+ _currentItemIndex = this . _leftIndex + ( this . _rightIndex - this . _leftIndex ) / 2 ;
150
106
151
- for ( int i = left ; i <= right ; i ++ )
107
+ if ( _leftIndex <= _rightIndex )
108
+ {
109
+ return true ;
110
+ }
111
+ else
152
112
{
153
- copyList . Add ( list [ i ] ) ;
113
+ return false ;
154
114
}
155
115
156
- return copyList ;
157
116
}
117
+
118
+
119
+ public void Reset ( ) { this . _currentItemIndex = - 1 ; }
120
+
121
+
122
+ public void Dispose ( ) { }
123
+
158
124
}
159
125
160
126
}
0 commit comments