1+ /**
2+ * @file exponential_search2.c
3+ * @brief Alternative implementation of [Exponential Search](https://en.wikipedia.org/wiki/Exponential_search).
4+ * @details
5+ * This version performs range expansion using safe bounds and a tight binary
6+ * search. It returns the index of the target in a sorted array or -1 if not found.
7+ * @author [hobostay](https://github.com/hobostay)
8+ */
9+
10+ #include <assert.h> /// for assert
11+ #include <stdio.h> /// for printf
12+
13+ /**
14+ * @brief Binary search within the closed interval [left, right]
15+ */
16+ static int bsearch_closed (const int * arr , int left , int right , int x ) {
17+ while (left <= right ) {
18+ int mid = left + (right - left ) / 2 ;
19+ int v = arr [mid ];
20+ if (v == x ) {
21+ return mid ;
22+ }
23+ if (v < x ) {
24+ left = mid + 1 ;
25+ } else {
26+ right = mid - 1 ;
27+ }
28+ }
29+ return -1 ;
30+ }
31+
32+ /**
33+ * @brief Exponential search on a sorted array
34+ * @param arr pointer to sorted array
35+ * @param n length of array
36+ * @param x target value to search for
37+ * @returns index of x if found, otherwise -1
38+ */
39+ int exponential_search2 (const int * arr , int n , int x ) {
40+ if (arr == NULL || n <= 0 ) {
41+ return -1 ;
42+ }
43+ if (arr [0 ] == x ) {
44+ return 0 ;
45+ }
46+ int bound = 1 ;
47+ while (bound < n && arr [bound ] < x ) {
48+ bound <<= 1 ; // double
49+ }
50+ int left = bound >> 1 ;
51+ int right = (bound < n ) ? bound : (n - 1 );
52+ return bsearch_closed (arr , left , right , x );
53+ }
54+
55+ /**
56+ * @brief Self tests for exponential_search2
57+ */
58+ static void test (void ) {
59+ printf ("Test 1.... " );
60+ int a1 [] = {1 , 3 , 5 , 7 , 9 , 11 , 13 , 15 };
61+ int n1 = (int )(sizeof (a1 ) / sizeof (a1 [0 ]));
62+ assert (exponential_search2 (a1 , n1 , 1 ) == 0 );
63+ assert (exponential_search2 (a1 , n1 , 15 ) == 7 );
64+ assert (exponential_search2 (a1 , n1 , 7 ) == 3 );
65+ assert (exponential_search2 (a1 , n1 , 4 ) == -1 );
66+ printf ("passed\n" );
67+
68+ printf ("Test 2.... " );
69+ int a2 [] = {-10 , -5 , -1 , 0 , 2 , 4 , 8 , 16 , 32 , 64 };
70+ int n2 = (int )(sizeof (a2 ) / sizeof (a2 [0 ]));
71+ assert (exponential_search2 (a2 , n2 , -10 ) == 0 );
72+ assert (exponential_search2 (a2 , n2 , 64 ) == 9 );
73+ assert (exponential_search2 (a2 , n2 , 32 ) == 8 );
74+ assert (exponential_search2 (a2 , n2 , 100 ) == -1 );
75+ printf ("passed\n" );
76+
77+ printf ("Test 3.... " );
78+ int a3 [] = {2 };
79+ int n3 = (int )(sizeof (a3 ) / sizeof (a3 [0 ]));
80+ assert (exponential_search2 (a3 , n3 , 2 ) == 0 );
81+ assert (exponential_search2 (a3 , n3 , 3 ) == -1 );
82+ printf ("passed\n" );
83+
84+ printf ("Test 4.... " );
85+ assert (exponential_search2 (NULL , 0 , 1 ) == -1 );
86+ printf ("passed\n" );
87+ }
88+
89+ /**
90+ * @brief Main function
91+ */
92+ int main (void ) {
93+ test ();
94+ return 0 ;
95+ }
0 commit comments