1
+ using System ;
2
+ using System . Collections . Generic ;
3
+
4
+
5
+ namespace Algorithms . Search
6
+ {
7
+ public static class BinarySearcher
8
+ {
9
+
10
+
11
+ /// <summary>
12
+ /// Apply Binary Search in a list.
13
+ /// </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
+ {
22
+ throw new NullReferenceException ( "List is null" ) ;
23
+ }
24
+
25
+ IList < T > sCollection = MergeSort < T > ( collection ) ;
26
+ int itemIndex = sCollection . InternalBinarySearch ( 0 , sCollection . Count - 1 , item ) ;
27
+ return itemIndex ;
28
+ }
29
+
30
+
31
+ /// <summary>
32
+ /// Apply MerseSort algorithm in a list.
33
+ /// </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 )
38
+ {
39
+ int mid = collection . Count / 2 ;
40
+ IList < T > leftList ;
41
+ IList < T > rightList ;
42
+
43
+ if ( collection . Count < 2 )
44
+ {
45
+ return collection ;
46
+
47
+ }
48
+
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 ) ;
56
+ }
57
+
58
+
59
+ /// <summary>
60
+ /// Merge two lists in ascending order.
61
+ /// </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 )
67
+ {
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 ;
99
+ }
100
+
101
+
102
+ /// <summary>
103
+ /// An implementation of binary search algorithm.
104
+ /// </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
+ /// <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 )
112
+ {
113
+ int mid = left + ( right - left ) / 2 ;
114
+ Comparer < T > comparer = Comparer < T > . Default ;
115
+
116
+ if ( left <= right )
117
+ {
118
+ if ( comparer . Compare ( item , collection [ mid ] ) < 0 )
119
+ {
120
+ return collection . InternalBinarySearch < T > ( left , mid - 1 , item ) ;
121
+ }
122
+ else if ( comparer . Compare ( item , collection [ mid ] ) > 0 )
123
+ {
124
+ return collection . InternalBinarySearch < T > ( mid + 1 , right , item ) ;
125
+ }
126
+ else
127
+ {
128
+ return mid ;
129
+ }
130
+ }
131
+ else
132
+ {
133
+ return - 1 ;
134
+ }
135
+
136
+ }
137
+
138
+
139
+ /// <summary>
140
+ /// Copies a range of a list to another list
141
+ /// </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 )
148
+ {
149
+ IList < T > copyList = new List < T > ( ) ;
150
+
151
+ for ( int i = left ; i <= right ; i ++ )
152
+ {
153
+ copyList . Add ( list [ i ] ) ;
154
+ }
155
+
156
+ return copyList ;
157
+ }
158
+ }
159
+
160
+ }
0 commit comments