C: Recursive function - Binary search - c

I'm trying to build a recursive function which returns the address within a sorted array by comparing to the middle value and proceeding based on relative size. Should the value not be in the array, it is supposed to simply print NULL. Now the first part of the function works, however whenever a null is supposed to happen I get a segmentation fault. The code looks as follows:
#include <stdio.h>
int *BinSearchRec(int arr[], int size, int n){
if(n==arr[size/2]){
return &arr[size/2];
}
else if(n>arr[size/2]) {
return(BinSearchRec(arr, size+size/2, n));
}
else if(n<arr[size/2]) {
return(BinSearchRec(arr, size-size/2, n));
}
else{
return NULL;
}
}
main(){
int numb[]={2,7,8,9};
if((int)(BinSearchRec(numb, 4, 22)-numb)>=0) {
printf("Position: %d \n", (int)(BinSearchRec(numb, 4, 22)-numb)+1);
}
else{
printf("NULL \n");
}
}

Your recursive calls are wrong. In the first case you claim that the size of the array is 50% larger than originally, and you're passing the pointer wrong (you should pass the second "half" of the array).
In both cases, the size of the "array" is always half of what the function received. And in the second case, you need to pass a pointer to the second half of the array.
Something like
else if(n>arr[size/2]) {
return(BinSearchRec(arr + sizeof/2, size/2, n));
}
else if(n<arr[size/2]) {
return(BinSearchRec(arr, size/2, n));
}
You're also treating the returned value from the function wrong. It's not a value, it's a pointer to the value, you need to treat it as such. And it's okay to subtract one pointer from another (related) pointer, it's called pointer arithmetics.

In addition to what others have said about not dividing the array properly and not using the return value correctly, your function is missing a termination condition.
In your code, the las else will never be reached, because the three preceding conditions cover all possibilities: n is either smaller than, equal to or greater than arr[size/2].
You should test whether your subarray actually has elements before you access and compare them. Here's a revision of your code:
int *BinSearchRec(int arr[], int size, int n)
{
int m = size/2;
if (size == 0) return NULL;
if (n > arr[m]) return BinSearchRec(arr + m + 1, size - m - 1, n);
if (n < arr[m]) return BinSearchRec(arr, m, n);
return &arr[m];
}
And here's an example main that shows how you make use of the pointer that was returned. If the pointer is NULL, the number is not in the array and you cannot dereference the pointer.
int main()
{
int numb[] = {2, 7, 8, 9};
int n;
for (n = 0; n < 15; n++) {
int *p = BinSearchRec(numb, 4, n);
if (p) {
printf("%d: #%d\n", n, (int) (p - numb));
} else {
printf("%d: NULL\n", n);
}
}
return 0;
}

Instead of using a single size, it is easier to reason with 2 indexes (left and right) delimiting the sub-array you are exploring.
Modifying your code according to this approach gives:
#include <stdio.h>
#include <stdlib.h>
int *BinSearchRec(int arr[], int left, int right, int n){
if (left > right)
return NULL;
int mid = (left + right) / 2;
if(n == arr[mid])
return &arr[mid];
if(n > arr[mid])
return BinSearchRec(arr, mid + 1, right, n);
else
return BinSearchRec(arr, left, mid - 1, n);
}
int main(int argc, char *argv[]){
int numb[] = {2,7,8,9};
int *p = BinSearchRec(numb, 0, 3, 22);
if (p) {
printf("Position: %d \n", (int) (p - numb + 1));
} else {
printf("NULL \n");
}
return 0;
}

Related

MInimum element in array ( C )

I'm a newbie both here in stackoverflow and both in the world of programming.
Today i was solving some exercise about recursion, and one of these asked to write a recursive function for finding minimum element of an array.
After many tries, I have finally wrote this working code, but i want to ask you if this is a "good" code. I mean, the fact it's working aside, is it written well? There's something that should be changed? And, above all, there's a way to make this functions working well without declaring that global int "min"? :)
Here's the code:
#include <stdio.h>
int recursiveMinimum(int array[], size_t size);
int min = 1000;
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
printf("\nMinimum element of this array is: %d\n\n",
recursiveMinimum(array, 6));
}
int recursiveMinimum(int array[], size_t size) {
if (size == 1) {
return min;
} else {
if (array[size] <= min) min = array[size];
return min = recursiveMinimum(array, size - 1);
}
}
It is a bad idea when a function depends on a global variable.
But in any case your function is incorrect and invokes undefined behavior.
In the first call of the function this if statement
if (array[size] <= min) min = array[size];
trying to access memory outside the passed array because the valid range of indices is [0, size).
Also the array can contain all elements greater than the initial value of the global variable
int min = 1000;
And the function may not be called a second time because the value of the variable min is unspecified.
The function should return the index of the minimal element in the array. In general the user can pass the second argument equal to 0. In this case again the function will invoke undefined behavior if you will try to return a non-existent element of an empty array.
The function can be declared and defined the following way
size_t recursiveMinimum( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
Here is a demonstration program
#include <stdio.h>
size_t recursiveMinimum( const int a[], size_t n )
{
if (n < 2)
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
int main( void )
{
int a[] = { 55, 5, 1, 27, 95, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t min = recursiveMinimum( a, N );
printf( "\nMinimum element of this array is: %d at the position %zu\n",
a[min], min );
}
The program output is
Minimum element of this array is: 1 at the position 2
Pay attention to that the first parameter has the qualifier const because the passed array is not being changed within the function. And to decrease the number of recursive calls the function calls itself for two halves of the array.
Recursion works by reducing the size at the call to the next iteration and comparing the result of the call with the current value and return the lower of the 2.
As recursion stop you can simply return the first element
int recursiveMinimum(int array[], size_t size) {
if (size == 1) return array[0];
int min_of_rest = recursiveMinimum(array, size - 1);
if (array[size - 1] <= min_of_rest) return array[size - 1];
return min_of_rest;
}
Full example: https://godbolt.org/z/sjnh8sYz3
In the past, we used to implement it with pointers, KR-C style.
Using pointers in a harsh way was a mean to deal with inefficiency of compilers at that time.
Not sure it is considered good practice now. An example is provided hereafter.
Anyway, it would be better (easier and more efficient) to implement it in a non recursive manner.
#include <stdio.h>
void recursiveMinimum(int *array, size_t size, int *min) {
if (size == 0) return;
if (*array < *min) *min = *array;
recursiveMinimum (array+1, size-1, min);
return;
}
int main(void) {
int array[] = {55, 5, 1, 27, 95, 2};
size_t size = sizeof(array)/sizeof(*array);
int min = array[0];
recursiveMinimum (array, size, &min);
printf("\nMinimum element of this array is: %d\n", min);
return 0;
}

Is a function recursive if it calls itself TRIVIALLY

I was asked to write a recursive code to print an array. A friend showed me this code:
include <stdio.h>
int i=0;
void print(int A[], int n)
{
if(i<n)
{
printf("%d ", A[i]);
i++;
print(A, n);
}
}
int main()
{
int A[3]={3, 5, 2};
print(A, 3);
return 0;
}
Technically, it is recursive because the function calls itself, but I think trivially !! It does not break the problem into smaller problems or anything like that. So, it felt like cheating. Faking as if it is recursion.
Can the function in this code be consider recursive? Is this a fine way to use recursion?
What about in this form:
#include <stdio.h>
void print(int A[], int n, int i)
{
if(i<n)
{
printf("%d ", A[i]);
print(A, n, i+1);
}
}
int main()
{
int A[3]={3, 5, 2}, i=0;
print(A, 3, i);
return 0;
}
Can the function in this code be consider recursive?
Yes, recursion occurs when the function can call itself, either directly or indirectly.
Is this a fine way to use recursion?
No. Although some compilers may optimize the code, code risks incurring n levels of recursion and causing stack overflow
A better alternative is to halve the problem. This breaks the problem in 2 at each step.
void print(int A[], int n, int i) {
if (i<n) {
A += i; n -= i; // zero offset A and n
int mid = n/2;
print(A, mid, 0); // print left side of A
printf("%d ", A[mid]); // print middle of A
int right = n - mid - 1;
print(A + mid + 1, right, 0); // print right side of A
}
}
If n was 1000, the above could incur a recursion depth of log2(1000) or about 10 instead of 1000. An unbounded n is a reason recursion can be abused. Insure that the recursion depth is not excessive.
Notice that parameter i is not really needed.
void printA(int A[], size_t n) {
if (n > 0) {
size_t mid = n/2;
printA(A, mid); // print left side of A
printf("%d ", A[mid]); // print middle of A
size_t right = n - mid - 1;
printA(A + mid + 1, right); // print right side of A
}
}
Yes, this is a recursive function, since it calls itself.
Additionally, the function does break the problem to smaller problems - in this case, precisely one smaller problem: printing the array starting from index i+1 instead from index i. Since the bound is greater than i, the problem is smaller.
In other words, the recursion is well founded: the value of n-i is decreasing at each call, and the edge case of n-i==0 is handled trivially, not recursively.
Regardless of the number of lines in a function, it is recursive if it calls itself.
void print(int A[], int n) {
if(n == 0)
printf("%d", *A);
print(++A, --n);
}
Instead of using static variable you can pass the starting element address and last elements address of the array and do the same task.
void print(int *A_start, int *A_end) {
if(A_start < A_end) { /* call the function itself until A_start not reaches A_end */
printf("%d ", *A_start);
A_start++;
print(A_start,A_end);
}
}
int main() {
int A[3]={3, 5, 2};
int ele = sizeof(A)/sizeof(A[0]);
print(A,A+ele);
return 0;
}

C recursive program to find the maximum element from array

So I have a task in my training that sounds like this:
Write a subprogram that will recursively find the maximum element from an array and also write the main function to call it.
What I failed to fully understand is what recursion is. I wanted to ask you guys if my code is recursive or not. And if not what changes should I make/ what recursion really means?
#include <stdio.h>
int find_maximum(int[], int);
int main() {
int c, array[100], size, location, maximum;
printf("Input number of elements in array\n");
scanf("%d", &size);
printf("Enter %d integers\n", size);
for (c = 0; c < size; c++)
scanf("%d", &array[c]);
location = find_maximum(array, size);
maximum = array[location];
printf("Maximum element location = %d and value = %d.\n", location + 1, maximum);
return 0;
}
int find_maximum(int a[], int n) {
int c, max, index;
max = a[0];
index = 0;
for (c = 1; c < n; c++) {
if (a[c] > max) {
index = c;
max = a[c];
}
}
return index;
}
Thank you all for your time!
Problems that are well-suited to recursion can be broken down into smaller, simpler subproblems. This is one of the things that gives recursion its power. When trying to use recursion to solve a problem, it usually seems best to try to break the problem down into simpler subproblems in finding your way to a solution.
You might notice that in finding the maximum value stored in an array, it is either the value of the first element, or the maximum value of the remaining elements. This breaks the problem into two parts: if the first element is larger than any remaining elements, you are done; otherwise, you must continue and see if the next element is larger than the remaining elements. In code, this might look like:
int max_in(size_t rest_sz, int *rest)
{
int curr_val = rest[0];
if (rest_sz == 1) {
return curr_val;
}
int max_in_rest = max_in(rest_sz-1, rest+1);
return curr_val > max_in_rest ? curr_val : max_in_rest;
}
Here, there is a base case: if rest_sz is 1, there is no need to look further; the value of first element (curr_val = rest[0]) is the maximum, and that value is returned. If the base case is not satisfied, execution of the function continues. max_in_rest is the result from the recursive function call max_in(rest_sz-1, rest+1). Here rest_sz-1 indicates the number of elements remaining in the portion of the array indicated by rest+1. In the new function call, the base case is met again, and eventually this case will be true since rest_sz is decremented with each recursive call. When that happens, the value of curr_val in the current stack frame will be returned; note that this value is the value of the last element in the array. Then, when the function returns to its caller, max_in_rest in that frame will get the returned value, after which the larger of curr_val or max_in_rest is returned to the previous caller, and so on, until finally control is returned to main().
Using pencil and paper to diagram each function call, the values of its variables, and what is returned would help to understand exactly how this recursion works.
You can apply the same method to solving the problem of finding the index of the maximum value of an array. In this case, if the value of the first element is greater than the value of any remaining elements, then the index of the maximum element is the index of the first element; otherwise the index of the maximum element is the index of the maximum value of the remaining elements. In code, this might look like:
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx)
{
if (rest_sz == 1) {
return curr_ndx;
}
int curr_val = arr[curr_ndx];
size_t max_in_rest_ndx = find_max_r(arr, rest+1, rest_sz-1, curr_ndx+1);
int max_in_rest = arr[max_in_rest_ndx];
return curr_val >= max_in_rest ? curr_ndx : max_in_rest_ndx;
}
There is just a little more information to keep track of this time. Here, if the base case is satisfied, and rest_sz is 1, then there is no reason to look further, the current index curr_ndx is the index of the maximum value. Otherwise, find_max_r() is recursively called, with rest incremented to point to the remaining elements of the array, and rest_sz suitably decremented. This time, curr_ndx is keeping track of the current index with respect to the original array, and this value is passed into each function call; also, a pointer to the first element of the original array, arr, is passed into each function call so the index value curr_ndx can access the values from the original array.
Again, when the base case is reached, the current position in the array will be the end of the array, so the first elements to be compared in the return statement will be towards the end of the array, moving towards the front of the array. Note that >= is used here, instead of > so that the index of the first maximum value is returned; if you instead want the index of the last maximum value, simply change this to >.
Here is a complete program. Note the use of the helper function find_max() to call the recursive function find_max_r(), which allows the caller to use a function with the same signature that the posted code uses (except for the use of size_t types, which is really the correct type for array indices):
#include <stdio.h>
int max_in(size_t sz, int *rest);
size_t find_max(size_t sz, int arr[]);
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx);
int main(void)
{
int array[] = { 2, 7, 1, 8, 2, 5, 1, 8 };
size_t array_sz = sizeof array / sizeof array[0];
int max_val = max_in(array_sz, array);
printf("Maximum value is: %d\n", max_val);
size_t max_ndx = find_max(array_sz, array);
printf("Maximum value index: %zu\n", max_ndx);
return 0;
}
int max_in(size_t rest_sz, int *rest)
{
int curr_val = rest[0];
if (rest_sz == 1) {
return curr_val;
}
int max_in_rest = max_in(rest_sz-1, rest+1);
return curr_val > max_in_rest ? curr_val : max_in_rest;
}
size_t find_max(size_t sz, int arr[])
{
int *rest = arr;
return find_max_r(arr, rest, sz, 0);
}
size_t find_max_r(int arr[], int *rest, size_t rest_sz, size_t curr_ndx)
{
if (rest_sz == 1) {
return curr_ndx;
}
int curr_val = arr[curr_ndx];
size_t max_in_rest_ndx = find_max_r(arr, rest+1, rest_sz-1, curr_ndx+1);
int max_in_rest = arr[max_in_rest_ndx];
return curr_val >= max_in_rest ? curr_ndx : max_in_rest_ndx;
}
Program output:
Maximum value is: 8
Maximum value index: 3
Think of calculating the maximum number in an array as the number which will be maximum of the first element and the maximum of the remaining elements of the array. Something like: max(first_elem, max(remaining_elems)).
The actual recursive function: find_max quite simple, if there is just a single element in the array, that element is returned. Otherwise, we get the maximum of the first element and the remaining elements of the array.
#include <stdio.h>
// function to find the max of 2 numbers
int max(int x, int y)
{
return (x > y) ? x : y;
}
// the recursive function
int find_max(int *p, int n)
{
if (n == 1) return *p;
return max(*p, find_max(p + 1, n - 1));
}
int main(void)
{
int arr[] = {23, 3, 11, -98, 99, 45};
printf("max: %d\n", find_max(arr, sizeof arr / sizeof arr[0]));
}
No, your code does not use recursion. Recursion is when a function calls itself, or calls another function which leads to a call to itself again.
You can change your code like this to have a recursive, stateless function that can determine the maximum value of the array.
int find_maximum(int a[], int n) {
return find_maximum_r(a, 0, n);
}
int find_maximum_r(int a[], int index, int n) {
if (index + 1 == n) {
return a[index];
}
int maxRight = find_maximum_r(a, index + 1, n);
return a[index] > maxRight ? a[index] : maxRight;
}
No, your code is recursive only if you call the function find_maximum from itself directly or indirectly.
As your function is trying to get not only the maximum value, but also the position in the array, I have modified slightly the interface to return the reference (that is, a pointer to the value) so we can infer the position of the array element directly from the subtraction of element pointers. This way, I can pass to the function the array pointer directly and the array size, and then divide the array in two halves, and applying the same function to the two halves (it can be demonstrated that if some element is the maximum value of the array, it has to be greater than or equal to each half's maximum) For the same reason, I have modified some of the variables defined in your main() function, to allow for references to be used:
max.c
#include <stdio.h>
#include <assert.h>
int *find_maximum(int a[], int n); /* return a reference pointer to the maximum value */
int main() {
int c, array[100], size, *location, /* location must be a pointer */
maximum;
printf("Input number of elements in array\n");
scanf("%d", &size);
assert(size >= 1);
printf("Enter %d integers\n", size);
for (c = 0; c < size; c++)
scanf("%d", &array[c]);
location = find_maximum(array, size);
maximum = *location; /* access to the value is granted by pointer dereference */
printf("Maximum element location = %td and value = %d.\n",
location - array, /* pointer difference gives the array position */
maximum);
return 0;
} /* main */
/* somewhat efficient recursive way of a divide and conquer method
* to get the maximum element reference. */
int *find_maximum(int a[], int n)
{
if (n == 1) return a; /* array of 1 element */
int *left = find_maximum(a, n/2), /* left half begins at a
* and has n/2 elements */
*right = find_maximum(a + n/2, (n+1)/2); /* right half begins
* at a + n/2, and
* has (n+1)/2
* elements */
return *left > *right
? left
: right;
} /* find_maximum */
As you see, I have to divide by two, but as I have arrays of any length, I have to be careful not to leave out any element in the next step. This is the reason for using an array of (n+1)/2 elements in the right half of the recursive call to the function. I include n/2 elements in the first half (rounding down), I have to include (n+1)/2 elements (rounding up) in the right half, to be sure that I include all the array elements in the two halves.
First of all, recursion means - function calling itself.
And what you've written is not recursive function. I'll post the most simple way to find biggest or largest element in an array, using recursion.
#include<stdio.h>
#define N 5
int biggest(int num[], int n, int big)
{
if(n < 0)
return big;
else
{
if(big < num[n])
big = num[n];
return biggest(num, --n, big);
}
}
int main()
{
int a[N], i;
printf("Enter %d integer number\n", N);
for(i = 0; i < N; i++)
scanf("%d", &a[i]);
printf("Biggest Element in the array: %d\n", biggest(a, N - 1, a[0]));
return 0;
}
Source: C Program To Find Biggest Element of An Array using Recursion
NO it is not recursive function
to know about recursion this link is very useful https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursion/
to make a recursion function to solve your problem try this
you can try this pseudo code declare your array global and a max=0 global and size global
int find_maximum(int i)
{
if (i == size )
return max;
else if ( max < array[i])
max =array [i];
return find_maximum(i+1);
}
where i is the array index
No, your program is certainly not recursive. As the definition, recursive function must call itself with a terminating condition.
Please read TutorialsPoint about recursion in C.
Update on #JonathanLeffler's comment:
Please note that the output in the reference will overflow.

C pointer arithmetic palindrome

I'm a java student who's currently learning about pointers and C.
I tried to make a simple palindrome tester in C using a single array and pointer arithmetic.
I got it to work without a loop (example for an array of size 10 :*(test) == *(test+9) was true.
Having trouble with my loop. School me!
#include<stdio.h>
//function declaration
//int palindrome(int *test);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
int *ptr;
ptr = &numArray[0];
output = palindrome(ptr);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test) {
int i;
for (i = 0; i <= (sizeof(test) / 2); i++) {
if (*(test + i) == *(test + (sizeof(test) - i)))
return 1;
else
return 0;
}
}
The Name of the array will itself acts as a pointer to an first element of the array, if you loose the pointer then there is no means for you to access the element of the array and hence you can send just the name of the array as a parameter to the function.
In the palindrome function:
you have used sizeof(test)/2. what happens is the address gets divided which is meaningless and hence you should not use that to calculate the mid element.
sizeof the pointer will be the same irrespective of the type of address that gets stored.
Why do you copy your pointer in another variable?
int *ptr;
ptr = &numArray[0];
Just send it to you function:
palindrome(numArray);
And sizeof(test) give you the memory size of a pointer, it's not what you want. You have to give the size in parameter of your function.
int palindrome(int *test, int size){
...
}
Finally your code must look like this:
#include<stdio.h>
int palindrome(int *test, int size);
int main()
{
int output;
int numArray[10] = {0,2,3,4,1,1,4,3,2,0};
output = palindrome(numArray, 10);
printf("%d", output);
}
//function determine if string is a palindrome
int palindrome(int *test, int size) {
int i;
for (i = 0; i < size / 2; i++) {
if (*(test + i) != *(test + (size - 1) - i))
return 0;
}
return 1;
}

algorithm-coin changing code mistake

Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.
I have written below code but it is always returning one less than the actual answer. I want to know if this is the right way of coding up the solution?
#include <stdio.h>
int ways=0;
int remember[100] = {0};
void foo(int coin_denomination[], int size, int sum)
{
int i;
printf("%d\n", sum);
if (sum==0) {
ways++;
return;
}
if (remember[sum]==1)
return;
remember[sum] = 1;
if (sum < 0)
return;
for(i=0;i<size;i++)
foo(coin_denomination, size, sum-coin_denomination[i]);
}
int main()
{
int coin_denomination[] = {1, 2, 3};
int sum = 5;
foo(coin_denomination, sizeof(coin_denomination)/sizeof(coin_denomination[0]), sum);
printf("%d\n", ways);
return 0;
}
You need some change to foo method. Your problem is that with the variable remember you are not counting some solutions. The goal of variable remember is not correct, you are using for not processing the same coin collection multiple times but you are saving only the sum of the coin collection and the sum could be obtained with multiple coin collections (ex: 1 1 1 have same sum that 1 2 when you select the second, remember[3] would be 1 and not be passing this point, missing solution 1 2 2)
Other way of not repeating coin collection is needed, in this case, adding a parameter that represent the index of coin_denomination that is processing and only allow processing of coin after, the problem is solve.
Code (Tested with GCC 4.9.0):
#include <stdio.h>
int ways=0;
void foo(int coin_denomination[], int size, int sum, int coin_idx = 0)
{
if (sum < 0)
return;
int i;
printf("%d\n", sum);
if (sum==0) {
ways++;
return;
}
for(i=coin_idx;i<size;i++)
foo(coin_denomination, size, sum-coin_denomination[i], i);
}
int main()
{
int coin_denomination[] = {1, 2, 3};
int sum = 5;
foo(coin_denomination, sizeof(coin_denomination)/sizeof(coin_denomination[0]), sum);
printf("%d\n", ways);
return 0;
}

Resources