Skip to content

Commit 57d2c29

Browse files
committed
feat(searching): add exponential_search2 implementation with self-tests and Doxygen header
1 parent b798cb8 commit 57d2c29

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

searching/exponential_search2.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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

Comments
 (0)