Recursive binary search function missing something? (C) - c

I'm trying to make a function that does a binary search on a sorted array. I've checked everything, and everything works correctly, except one thing:
If I don't put a return statement in the end of the function, not surrounded by If's, It won't build my program. If I put 'return 0', it would always return 0, no matter what. If I'll do the same with 1, it would always return 1, and I can't see where is my problem. Would love some help.
#include <stdio.h>
#define N 4
int search_matrix(int a[N][N], int x);
int binsearch(int a[], int x, int low, int high);
int main(){
int a[N][N];
printf("Please Enter Matrix : \n");
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
scanf("%d",&a[i][j]);
}//forj
}//fori
printf("Please enter x : \n");
int x;
scanf("%d",&x);
printf("%d\n",search_matrix(a,x));
return 0;
}
int search_matrix(int a[N][N], int x){
if(x>a[0][N-1]||x<a[N-1][0])
return 0;
int savedIndex=0;
for(int i=0;i<N;i++){
if(x>a[i][0]){
savedIndex=i;
break;
}
}//for
return(binsearch(a[savedIndex],x,0,N));
}//search_matrix
//------- THE PROBLEMATIC FUNCTION! ---------
int binsearch(int a[], int x, int low, int high) {
int mid;
if (low > high)
return 0;
mid = (low + high) / 2;
if (x == a[mid]) {
return 1;
} else if (x < a[mid]) {
binsearch(a, x, low, mid - 1);
} else {
binsearch(a, x, mid + 1, high);
}
}

Check it out:
#include<stdio.h>
#define N 4
int search_matrix(int a[N][N], int x);
int binsearch(int a[], int x, int low, int high);
int main(){
int a[N][N], i, j;
printf("Please Enter Matrix : \n");
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%d",&a[i][j]);
}//forj
}//fori
printf("Please enter x : \n");
int x;
scanf("%d",&x);
printf("%d\n",search_matrix(a,x));
return 0;
}
int search_matrix(int a[N][N], int x){
if(x>a[0][N-1]||x<a[N-1][0])
return 0;
int savedIndex=0, i;
for(i=0;i<N;i++){
if(x>a[i][0]){
savedIndex=i;
break;
}
}//for
return(binsearch(a[savedIndex],x,0,N));
}//search_matrix
//------- THE PROBLEMATIC FUNCTION! ---------
int binsearch(int a[], int x, int low, int high) {
int mid;
if (low > high)
return 0;
mid = (low + high) / 2;
if (x == a[mid]) {
return 1;
} else if (x < a[mid]) {
binsearch(a, x, low, mid - 1);
} else {
binsearch(a, x, mid + 1, high);
}
}

Related

Binary Search Algo

I've implemented a binary search, the code is below, but I want to edit the code so that It print also the history of the algorithm
For exmaple:
Initial array:
1 1 2 4 4 5
Target element: 3
Search history: 2(2) 4(4)
No targets
#include <stdio.h>
int search(int array[], int x, int low, int high);
int main(void)
{
int array[] = {1, 1, 2, 4, 4, 5};
int n = sizeof(array) / sizeof(array[0]);
int x = 3;
printf("Initial array:\n");
for (int i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n");
printf("Target element: %d\n", x);
int result = search(array, x, 0, n - 1);
(result == -1) ? printf("No targets\n") : printf("Element found at index %d\n", result);
}
int search(int array[], int x, int low, int high)
{
if (high >= low)
{
int mid = low + (high - low) / 2;
if (array[mid] == x)
{
return mid;
}
if (array[mid] > x)
return search(array, x, low, high - 1);
else
return search(array, x, low + 1, high);
}
return -1;
}
well, even though the question is not clear to me by what do you mean history of algorithm, but I assumed you want to print the number (of times) your algorithm is failed to get the key.
If I guessed right, you could do it by using an extra variable, which holds the number, your algorithm miss the hit (or key).
#include <stdio.h>
int search(int array[], int x, int low, int high, int failed);
int main(void)
{
int array[] = {1, 1, 2, 4, 4, 5};
int n = sizeof(array) / sizeof(array[0]);
int x = 5;
int failed = 0;
printf("Initial array:\n");
for (int i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n");
printf("Target element: %d\n", x);
int result = search(array, x, 0, n - 1, failed);
(result == -1) ? printf("No targets\n") : printf("Element found at index %d\n", result);
}
int search(int array[], int x, int low, int high, int failed)
{
if (high >= low)
{
int mid = low + (high - low) / 2;
if (array[mid] == x)
{
return mid;
}else{
// number of times you, failed to hit the key (item to be searched)
failed += 1;
printf("%i(%i) ", failed, array[mid]);
}
if (array[mid] > x)
return search(array, x, low, high - 1, failed);
else
return search(array, x, low + 1, high, failed);
}
return -1;
}

Expression must have arithmetic type

While trying to write a code to find the intersection of two arrays,I came across a problem. I can't seem to modify a pointer inside a function.
Inside my find_intersection I get the error while doing the realloc function,compiler states that "counter" has no arithmetic value.
Any explanation on what went wrong here?
#include <stdio.h>
#include <stdlib.h>
int quick_sort(int*, int, int);
void swap(int*, int*);
int partition(int *, int, int);
int input_array_dyn(int*n);
int *find_intersection(int*, int*, int*, int, int,int *);
main()
{
int size1, size2, *counter, i=0;
int *arr1 = input_array_dyn(&size1);
int *arr2 = input_array_dyn(&size2);
quick_sort(arr1, 0, size1 - 1);
quick_sort(arr2, 0, size2 - 1);
int *arr3 = (int*)calloc(size2, sizeof(int));
arr3= find_intersection(arr1, arr2, arr3, size1, size2, &counter);
printf("The size of the new array is:%d\n", counter);
while (i < counter)
{
printf("%d\n", arr3[i]);
i++;
}
free(arr1);
free(arr2);
free(arr3);
}
int *find_intersection(int *arr1, int *arr2, int *arr3, int SA, int SB, int *counter)
{
int i = 0, j = 0, n = 0;
*counter = 0;
while (i < SA &&j < SB)
{
if (arr1[i] < arr2[j])
i++;
else if (arr2[j] < arr1[i])
j++;
else
{
arr3[n] = arr1[i];
i++;
n++;
j++;
}
}
counter = n;
arr3 = (int*)realloc(arr3, counter*sizeof(int));/*error here*/
return arr3;
}
int input_array_dyn(int*n)
{
int i;
int *a;
printf("Enter the size of the array:\n");
scanf("%d", n);
a = (int*)calloc(*n, sizeof(double));
assert(a);
printf("Enter the array elements:%d.\n", *n);
for (i = 0; i < *n; i++)
scanf("%d", a + i);
return a;
}
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
int partition(int *arr, int low, int high)
{
int pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
if (arr[j] <= pivot)
{
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
int quick_sort(int *arr, int low, int high)
{
if (low < high)
{
int pi = partition(arr, low, high);
quick_sort(arr, low, pi - 1);
quick_sort(arr, pi + 1, high);
}
}
In find_intersection() counter is a pointer to an int. To change it's value you need to use *counter instead of counter.
return arr3; attempts to return a pointer to int while function is declared to return just int. counter is a pointer to an int while you are using it as an regular int setting to 0 and so on.

Get a series of lower case letters sorted

The algorithm works fine with integers but since I converted them into char, it has been printing null for the output:
/* sort a series of lower case letters using quicksort algorithm. */
#include <stdio.h>
#define N 10
// since c gets the ascii code when returning an int for a char variable.
char quicksort(char a[], char low, char high);
char split(char a[], char low, char high);
int a[N];
int main(void)
{
int i;
printf("Enter letters to be sorted: ");
for (i = 0; i < N; i++)
scanf("%d", &a[i]);
quicksort(a, 0, N - 1);
printf("In sorted order: ");
for (i = 0; i < N; i++)
printf("%s ", a[i]);
printf("\n");
return 0;
}
char quicksort(char a[], char low, char high)
{
int middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
char split(char a[], char low, char high)
{
char part_element = a[low];
for (;;) {
while (low < high && part_element <= a[high])
high--;
if (low >= high) break;
a[low++] = a[high];
while (low < high && a[low] <= part_element)
low++;
if (low >= high) break;
a[high--] = a[low];
}
a[high] = part_element;
return high;
}
Three issues:
a is declared as an array of int, but all your functions handle an array of char. This means they won't iterate through the array correctly. Change it to char a[N].
To read a character, use the %c format specifier to scanf.
To print a character, use the %c format specifier to printf.
The revised code still doesnt work and i cant seem to find the bug.
Your problems appear to be with main() pretty much along the lines that other folks have suggested with respect to using char oriented data instead of int. There are some non fatal questionable choice issues like using char datatypes for array indexes; quicksort() is declared to return char but returns nothing; and so forth. Below is a rework of your code, mostly for style, incorporating various folks suggestions:
/* sort a series of letters using quicksort algorithm. */
#include <stdio.h>
#define N (10)
void quicksort(char a[], int low, int high);
int split(char a[], int low, int high);
int main(void)
{
char a[N];
printf("Enter letters to be sorted: ");
for (int i = 0; i < N; i++) {
scanf("%c", &a[i]);
}
quicksort(a, 0, N - 1);
printf("In sorted order: ");
for (int i = 0; i < N; i++) {
printf("%c ", a[i]);
}
printf("\n");
return 0;
}
void quicksort(char a[], int low, int high)
{
if (low < high) {
int middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
}
int split(char a[], int low, int high)
{
char part_element = a[low];
for (;;) {
while (low < high && part_element <= a[high]) {
high--;
}
if (low >= high) {
break;
}
a[low++] = a[high];
while (low < high && a[low] <= part_element) {
low++;
}
if (low >= high) {
break;
}
a[high--] = a[low];
}
a[high] = part_element;
return high;
}
Does it not do everything it's supposed to?
EXAMPLE
> ./a.out
Enter letters to be sorted: aadircslne
In sorted order: a a c d e i l n r s
>
scanf requires a %c format specifier. Your scanf should change to
scanf("%c", &a[i]);
As a result, you should redeclare the a array to char, not int.

How can I make this recursive Binary Search program exit and not crash if the number is not found?

How can I prevent this program from crashing if the value the user searched for is not found? (When I try to implement an if/else or count system, the program doesn't work correctly)
#include <stdio.h>
#include "simpio.h"
#include "genlib.h"
#define start 0
void bubble(int numbers[]);
int binary(int val, int numbers[], int low, int high);
void io(int numbers[]);
int size;
main()
{
int result, search;
printf("This program sorts and searches an array\n");
printf("How many numbers would you like to sort and search?\n");
size = GetInteger()-1;
int numbers[size];
printf("Enter the numbers\n");
io(numbers);
bubble(numbers);
printf("Which number would you like to search for?\n");
search = GetInteger();
result = binary(search,numbers,start,size);
printf("The number %d was found at index %d\n",search,result+1);
}
void io(int numbers[])
{
int ink;
for(ink=0;ink<=size;ink++)
{
numbers[ink] = GetInteger();
}
}
void bubble(int numbers[])
{
int first,second,count,swap;
while(TRUE)
{
for(first=0,second=1,count=0;second<=size;first++,second++)
{
if(numbers[first]>numbers[second])
{
count++;
swap = numbers[first];
numbers[first]= numbers[second];
numbers[second] = swap;
}
}
if(count==0)break;
}
}
int binary(int val, int numbers[], int low, int high)
{
int mid;
mid = (low+high)/2;
if(val==numbers[mid]||low>high) return mid;
if(val>numbers[mid]) return(binary(val,numbers,mid,high));
else if(val<numbers[mid]) return(binary(val,numbers,low,mid));
}
change to
size = GetInteger();
int numbers[size--];//change size to max index
//..
int binary(int val, int numbers[], int low, int high)
{
int mid;
if(low>high)//if not found!
return -1;//check return value at main
mid = (low+high)/2;
if(val==numbers[mid]) return mid;
if(val>numbers[mid]) return(binary(val,numbers,mid+1,high));
else if(val<numbers[mid]) return(binary(val,numbers,low,mid-1));
}

Assignment makes pointer without a cast

I am editing a quick sort code so that the values of low, high, and middle point to an array element instead of integers.
This is my code:
#include <stdio.h>
#define N 10
void quicksort(int a[], int *low, int *high);
int split(int a[], int *low, int *high);
int main(void)
{
int a[N], i;
printf("Enter %d numbers to be sorted: ", N);
for (i=0; i<N; i++)
scanf("%d", &a[i]);
quicksort(a, &a[0], &a[N-1]);
printf("In sorted order: ");
for (i=0; i<N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
void quicksort(int a[], int *low, int *high)
{
int *middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
int split(int a[], int *low, int *high)
{
int part_element = *low;
for (;;) {
while (low < high && part_element <= *high)
high--;
if (low >= high) break;
*low++ = *high;
while (low < high && *low <= part_element)
low++;
if (low >= high) break;
*high-- = *low;
}
*high = part_element;
return *high;
}
I'm getting the error message:
qs.c:32:12: warning: assignment makes pointer from integer without a cast [enabled by default]
middle = split(a, low, high);
^
Can someone help me with this? Still a beginner at programming. All types of help are appreciated.
The problem is in this statement.
middle = split(a, low, high);
because middle is a pointer variable whereas split is a function which returns integer value not a pointer to an integer.
You are assigning integer value to a pointer variable middle .
You are not allowed to do that. :)
May be this will help you.
Change 'split()' to return an 'int *' instead of 'int'.
Change the last line of the 'split()' function from:
return *high;
to
return high;
Perhaps this would work better:
#include <stdio.h>
#define N 10
void quicksort(int a[], int *low, int *high);
int *split(int a[], int *low, int *high);
int main(void)
{
int a[N], i;
printf("Enter %d numbers to be sorted: ", N);
for (i=0; i<N; i++)
scanf("%d", &a[i]);
quicksort(a, &a[0], &a[N-1]);
printf("In sorted order: ");
for (i=0; i<N; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
void quicksort(int a[], int *low, int *high)
{
int *middle;
if (low >= high) return;
middle = split(a, low, high);
quicksort(a, low, middle - 1);
quicksort(a, middle + 1, high);
}
int *split(int a[], int *low, int *high)
{
int part_element = *low;
for (;;) {
while (low < high && part_element <= *high)
high--;
if (low >= high) break;
*low++ = *high;
while (low < high && *low <= part_element)
low++;
if (low >= high) break;
*high-- = *low;
}
*high = part_element;
return high;
}

Resources