I tried to write a function that performs binary search. the code I wrote is as follows:
int binarySearch (int num[], int value, int left, int right)
{
if (left > right)
return -1;
else
{
int middle = (left+right)/2;
if (num[middle] = value)
return middle;
else
{
if (value < num[middle])
return binarySearch(num, value, left, middle-1);
else
return binarySearch(num, value, middle+1, right);
}
}
return 0;
}
void main()
{
int num[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int result;
result = binarySearch(num,6,0,15);
printf("The result is: %d", result);
}
While trying to debug it I found out the num[] array doesn't being send into the function. When I look at the array outside of the function it contains 16 numbers. when I jump into the function with F11 the array that arr[] receives contains only 0. Nothing I try seems to solve it. Does someone understands what goes wrong?
Thank you very much,
Robert
In binarySearch function num acts as pointer. So, when you debug, it shows only first value (0) pointed by num.
If you want to pass a single-dimension array as an argument in a function, you would have to declare a formal parameter in one of following three ways and all three declaration methods produce similar results because each tells the compiler that an integer pointer is going to be received.
int func(int arr[], ...){
.
.
.
}
int func(int arr[SIZE], ...){
.
.
.
}
int func(int* arr, ...){
.
.
.
}
However, by mistake you did an assignment instead of comparison, in if (arr[middle] = value).
Thanks !!!
Arrays cannot be sent as function arguments in C. Arguments declared as array are converted to pointers that point at the element of array, according to N1570 6.7.6.3.
Arrays used in expressions are automatically converted to pointers pointing the first element of the array except for some exceptions such as operands of unary & operator and sizeof operator, according to N1570 6.3.2.1.
Therefore, the acutual type of arr is int* and it seems that the debugger recognized only the elemente pointed at directly by the pointer.
There are a few syntax errors that are stopping your code from working. (e.g. while loop has a ";" ignoring the loop content).
The biggest issue with your code is that you calculated the middle index incorrectly.
Incorrect:
middle = (left + right) / 2;
Correct:
middle = ((right - left) / 2) + left;
You need to subtract to get the actual distance between left and right, then divide by 2 to get the middle. Then add back to the smaller value to reach the middle between the left and right sides.
Here is your code with syntax fixed and a mid function to make things easier. Enjoy.
int mid(int min, int max) {
return ((max - min) / 2) + min;
}
int binarySearch(int value, int arr[], int left, int right)
{
int middle = mid(left,right);
while (left < right)
{
if (arr[middle] == value)
return middle;
if (value < arr[middle])
middle = mid(left, middle);
else
middle = mid(middle, right);
}
return -1;
}
You should just use the int * syntax in your function signature. C will handle this by passing a pointer to the first element of the array. In C, arrays are not passed like they are in Java or other high-level languages.
Note that you can still use the [] operator on a pointer, similarly to an array. In your example, you can refer to the 2nd element of the array by using this syntax:
int x = num[1]; /* get the second element of the num array */
This would be the updated function (copied "as is" from the original), with only changes made specific to the array usage:
int binarySearch (int *num, int value, int left, int right)
{
if (left > right)
return -1;
else
{
int middle = (left+right)/2;
if (num[middle] = value)
return middle;
else
{
if (value < num[middle])
return binarySearch(num, value, left, middle-1);
else
return binarySearch(num, value, middle+1, right);
}
}
return 0;
}
void main()
{
int num[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int result;
result = binarySearch(num,6,0,15);
printf("The result is: %d", result);
}
One additional thing that you typically need to do is pass the length of the array as a separate argument. This is so that the function can know how many elements are in the array. C does not automatically pass the array length the pointer to the first array element, so you have to take care of it manually.
The OP's code does not use the length of the array, so length is not added to that function signature. However, requiring access to the length of a C array and passing it to a function is so common that it bears an clear example. Consider this example function to sum the values of an array:
int summation_function(int * array, size_t length)
{
int sum = 0;
size_t i = 0;
for (; i < length; ++i) {
sum += array[i];
}
return sum;
}
To call summation_function, you can do something like this:
int values[] = {1,2,4,8,16,32};
int sum = summation_function(values, sizeof(values)/sizeof(int));
printf("Summation of the values [1,2,4,8,16,32] is %d\n", sum);
Note the use of this code in this example:
sizeof(num)/sizeof(int)
What this does is find the allocated number of bytes in the array (the sizeof(num)) and divide by the number of bytes in an int (the sizeof(int)). The result is the exact number of elements in the array. With this, you can avoid hard-coding array lengths. This code is idiomatic of C array handling, so it becomes second nature to understand it after the first few uses.
Related
I have two functions in my main function.
I've tried to accomplish this problem with pointers, but as a beginner, it is very complicated to work with this.
int main(){
int *p;
p = function_A();
function_B(p);
return 0;
}
int function_A(){
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
return myArray;
}
int function_B(int *myPointer){
// Here I just want to print my array I've got from function_A() to the
// console
printf("%d", *myPointer)
return 0;
}
function_A should return a array and function_B should take this array.
Thanks!
There are some issues your compiler will already have told you.
First, you should define the functions before calling them, or at least forward declare them.
Second, to return an array, you need to return a pointer to the first element of this array, i.e. return type is int * and not int.
Third, as FredK pointed out, when you receive just a pointer, you have no chance to determine how many elements are in the array it points to. You can either terminate the array with a specific value, e.g. 0, or you need to return the size of the array, too.
See the following adaptions made to your program:
int* function_A(int *size){
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
if (size) {
*size = 3;
}
return myArray;
}
void function_B(int *myPointer, int size){
for (int i=0; i<size; i++) {
printf("%d\n", myPointer[i]);
}
}
int main(){
int *p;
int size=0;
p = function_A(&size);
function_B(p,size);
return 0;
}
Note: a reference to an array degrades to the address of the first byte of the array.
the following proposed code:
cleanly compiles
incorporates the comments to the question
assumes the programmer already knows the size of the array
performs the desired functionality
appended '\n' to format string of calls to printf() so output on separate lines
and now, the proposed code:
#include <stdio.h>
int * function_A( void );
void function_B(int *myPointer);
int main( void )
{
int *p;
p = function_A();
function_B(p);
return 0;
}
int * function_A()
{
static int myArray[3];
myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
return myArray;
}
void function_B(int *myPointer)
{
printf("%d\n", myPointer[0]);
printf("%d\n", myPointer[1]);
printf("%d\n", myPointer[2]);
}
a run of the program produces the following output:
11
22
33
Let's say you have a function that creates an array of ints:
int *create_int_array(const size_t num)
{
int *iarray;
size_t i;
if (num < 1)
return NULL; /* Let's not return an empty array. */
iarray = malloc(num * sizeof iarray[0]);
if (!iarray)
return NULL; /* Out of memory! */
/* Fill in the array with increasing integers. */
for (i = 0; i < num; i++)
iarray[i] = i + 1;
return iarray;
}
Let's say tou have a function that calculates the sum of the integers in the array. If we ignore any overflow issues, it could look like this:
int sum_int_array(const int *iarray, const size_t num)
{
int sum = 0;
size_t i;
/* Sum of an empty array is 0. */
if (num < 1)
return 0;
for (i = 0; i < num; i++)
sum += iarray[i];
return sum;
}
Note that sizeof is not a function, but a C language keyword. Its argument is only examined for its size. Thus, sizeof iarray[0] yields the size of each element in iarray, and is completely safe and valid even if iarray is undefined or NULL at that point. You see that idiom a lot in C programs; learn to read it as "size of first element of iarray", which is the same as "size of each element in iarray", because all C array elements have the exact same size.
In your main(), you could call them thus:
#ifndef NUM
#define NUM 5
#endif
int main(void)
{
int *array, result;
array = create_int_array(NUM);
if (!array) {
fprintf(stderr, "Out of memory!\n");
exit(EXIT_FAILURE);
}
result = sum_int_array(array, NUM);
printf("Sum is %d.\n", result);
free(array);
return EXIT_SUCCESS;
}
As you can see, there is really not much to it. Well, you do need to get familiar with the pointer syntax.
(The rule I like to point out is that when reading pointer types, read the specifiers from right to left, delimited by * read as a pointer to. Thus, int *const a reads as "a is a const, a pointer to int", and const char **b reads as "b is a pointer to a pointer to const char".)
In this kind of situations, a structure describing an array makes much more sense. For example:
typedef struct {
size_t max; /* Maximum number of elements val[] can hold */
size_t num; /* Number of elements in val[] */
int *val;
} iarray;
#define IARRAY_INIT { 0, 0, NULL }
The idea is that you can declare a variable of iarray type just as you would any other variable; but you also initialize those to an empty array using the IARRAY_INIT macro. In other words, thus:
iarray my_array = IARRAY_INIT;
With that initialization, the structure is always initialized to a known state, and we don't need a separate initialization function. We really only need a couple of helper functions:
static inline void iarray_free(iarray *array)
{
if (array) {
free(array->val);
array->max = 0;
array->num = 0;
array->val = NULL;
}
}
/* Try to grow the array dynamically.
Returns the number of elements that can be added right now. */
static inline size_t iarray_need(iarray *array, const size_t more)
{
if (!array)
return 0;
if (array->num + more > array->max) {
size_t max = array->num + more;
void *val;
/* Optional: Growth policy. Instead of allocating exactly
as much memory as needed, we allocate more,
in the hopes that this reduces the number of
realloc() calls, which tend to be a bit slow.
However, we don't want to waste too much
memory by allocating and then not using it. */
if (max < 16) {
/* Always allocate at least 16 elements, */
max = 16;
} else
if (max < 65536) {
/* up to 65535 elements add 50% extra, */
max = (3*max) / 2;
} else {
/* then round up to next multiple of 65536, less 16. */
max = (max | 65535) + 65521;
}
val = realloc(array->val, max * sizeof array->val[0]);
if (!val) {
/* We cannot grow the array. However, the old
array is still intact; realloc() does not
free it if it fails. */
return array->max - array->num;
}
/* Note: the new elements in array->val,
array->val[array->max] to
array->val[max-1], inclusive,
are undefined. That is fine, usually,
but might be important in some special
cases like resizing hash tables or such. */
array->max = max;
array->val = val;
}
return array->max - array->num;
}
/* Optional; same as initializing the variable to IARRAY_INIT. */
static inline void iarray_init(iarray *array)
{
array->max = 0;
array->num = 0;
array->val = NULL;
}
The static inline bit means that the functions are only visible in this compilation unit, and the compiler is free to implement the function directly at the call site. Basically, static inline is used for macro-like functions and accessor functions. If you put the structure in a header file (.h), you'd put the related static inline helper functions in it as well.
The growth policy part is only an example. If you omit the growth policy, and always reallocate to array->num + more elements, your code will call realloc() very often, potentially for every int appended. In most cases, doing it that often will slow down your program, because realloc() (as well as malloc(), calloc()) is kind-of slow. To avoid that, we prefer to pad or round up the allocation a bit: not too much to waste allocated but unused memory, but enough to keep the overall program fast, and not bottlenecked on too many realloc() calls.
A "good growth policy" is very much up to debate, and really depends on the task at hand. The above one should work really well on all current operating systems on desktop machines, laptops, and tablets, when the program needs only one or only a handful of such arrays.
(If a program uses many such arrays, it might implement an iarray_optimize() function, that reallocates the array to exactly the number of elements it has. Whenever an array is unlikely to change size soon, calling that function will ensure not too much memory is sitting unused but allocated in the arrays.)
Let's look at an example function that uses the above. Say, the obvious one: appending an integer to the array:
/* Append an int to the array.
Returns 0 if success, nonzero if an error occurs.
*/
int iarray_append(iarray *array, int value)
{
if (!array)
return -1; /* NULL array specified! */
if (iarray_need(array, 1) < 1)
return -2; /* Not enough memory to grow the array. */
array->val[array->num++] = value;
return 0;
}
Another example function would be one that sorts the ints in an array by ascending or descending value:
static int cmp_int_ascending(const void *ptr1, const void *ptr2)
{
const int val1 = *(const int *)ptr1;
const int val2 = *(const int *)ptr2;
return (val1 < val2) ? -1 :
(val1 > val2) ? +1 : 0;
}
static int cmp_int_descending(const void *ptr1, const void *ptr2)
{
const int val1 = *(const int *)ptr1;
const int val2 = *(const int *)ptr2;
return (val1 < val2) ? +1 :
(val1 > val2) ? -1 : 0;
}
static void iarray_sort(iarray *array, int direction)
{
if (array && array->num > 1) {
if (direction > 0)
qsort(array->val, array->num, sizeof array->val[0],
cmp_int_ascending);
else
if (direction < 0)
qsort(array->val, array->num, sizeof array->val[0],
cmp_int_descending);
}
}
Many new programmers do not realize that the standard C library has that nifty and quite efficient qsort() function for sorting arrays; all it needs is a comparison function. If the direction is positive for iarray_sort(), the array is sorted in ascending order, smallest int first; if direction is negative, then in descending order, largest int first.
A simple example main() that reads in all valid ints from standard input, sorts them, and prints them in ascending order (increasing value):
int main(void)
{
iarray array = IARRAY_INIT;
int value;
size_t i;
while (scanf(" %d", &value) == 1)
if (iarray_append(&array, value)) {
fprintf(stderr, "Out of memory.\n");
exit(EXIT_FAILURE);
}
iarray_sort(&array, +1); /* sort by increasing value */
for (i = 0; i < array.num; i++)
printf("%d\n", array.val[i]);
iarray_free(&array);
return EXIT_SUCCESS;
}
If size of array is indeed 3 (or other small fixed value), then you can simply use structs as values, something like:
struct ints3 {
int values[3];
// if needed, can add other fields
}
int main(){
struct ints3 ints;
ints = function_A();
function_B(&ints);
return 0;
}
// note about function_A signature: void is important,
// because in C empty () means function can take any arguments...
struct ints3 function_A(void) {
// use C designated initialiser syntax to create struct value,
// and return it directly
return (struct ints3){ .values = { 11, 22, 33 } };
}
int function_B(const struct ints3 *ints) {
// pass struct as const pointer to avoid copy,
// though difference to just passing a value in this case is insignificant
// could use for loop, see other answers, but it's just 3 values, so:
printf("%d %d %d\n", ints->values[0], ints->values[1], ints->values[2]);
return 0; // does this function really need return value?
}
I'm unable to interpret how come we are giving arr [] as arr+n-d in the leftrotate function. The comment HERE marks the line I'm talking about.
Block swap algorithm:
void printArray(int arr[], int size);
void swap(int arr[], int fi, int si, int d);
void leftRotate(int arr[], int d, int n)
{
if(d == 0 || d == n)
return;
if(n-d == d)
{
swap(arr, 0, n-d, d);
return;
}
if(d < n-d)
{
swap(arr, 0, n-d, d);
leftRotate(arr, d, n-d);
}
else
{
swap(arr, 0, d, n-d);
leftRotate(arr+n-d, 2*d-n, d); // HERE
}
}
void swap(int arr[], int fi, int si, int d)
{
int i, temp;
for(i = 0;i<d;i++)
{
temp = arr[fi + i];
arr[fi + i] = arr[si + i];
arr[si + i] = temp;
}
}
http://www.geeksforgeeks.org/block-swap-algorithm-for-array-rotation/
Whenever you pass an array as a parameter, only the address of that array is passed. You can read about this here
Suppose you have declared an array arr as int arr[] = {1,2,3,4,5,6,7,8,9,10};
Now if you call printf(arr); It returns the base address of arr (address of starting element of array)
If you type printf(arr[i]) the compiler interprets arr[i] as *(arr + i) and returns the value at address arr + i.
Arrays in C\C++ are accessed using pointer arithmetic.
Now coming to your question:
leftRotate(arr+n-d, 2*d-n, d); // HERE
We recursively call leftRotate() because we have shifted the B part of array with Al. Now the B part is at its final location and we can forget about it.
We now focus our attention on arr starting from element arr[n-d] to put those elements at their correct place.
So, the first argument of above function gives the address of element arr[n-d] and like dave_thompson_085 commented it's a bad practice because the type of that argument is not explicitly mentioned.
The second argument gives us the number of elements remaining to be shifted and the third argument gives us the size of array.
You can read more about arrays and pointers here:
Difference between pointer and array in C
Pointer vs Array in C
Arrays, String Constants and Pointers
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.
me and my friend are trying to pass a user-defined array to a function and do a "2d array" sort mechanism on that array which is defined outside the function.
we found a function online that sorts a predefined array within itself and tried to use that function.
our problem consist in trying to use the user-defined array in the function.
please check the code below (please note that we don't know how to use structs)
The question is: how do we use our orderListArray[][] in the sort array function?
#include <stdio.h>
#include <stdlib.h>
// define for sort array function later on
#define ARRAYSIZE(array) (sizeof(array)/sizeof(*(array)))
// function prototype
int sortArray();
int printOrderlist();
// data variables to be used throughout the code.
int itemNumber;
int itemAmount;
int maxItem = 0;
int lineCount = 0;
int priceToPrint = 0;
float totalPrice = 0;
// array we wish to implement into "sortArray" function
int orderListArray[][2];
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
int orderList()
{ // begin orderList
// makes sure user enters a maximum of 5 orders
int k = 0; // first place in array
int g = 0; // second place in array
do
{ // begin do1
printf("%d %d\n", k,g);
// asks for item number
puts("Enter item number (1-100):");
scanf("%d", &itemNumber);
// add scan to first spot (k) which is 0,0 (row 0, spot 0)
orderListArray[k][g] = itemNumber;
// add g++ to go to 0,1 ( row 0, spot 1)
g++;
// asks for amount
printf("%d %d\n", k, g);
printf("You can order %d more items\n", 5-itemAmount);
printf("Enter amount:\n");
scanf("%d", &itemAmount);
maxItem = maxItem + itemAmount;
// add itemAmount to g which is 0,1
orderListArray[k][g] = itemAmount;
k++; // go to row 1 instead of row 0
g--; // go back to spot 0 in row.
// lineCount is used when we print rows of array since that is not predefined
lineCount++;
} // end do1
// runs as long as the total amount of items inputed matches.
while (maxItem <= 4);
return 0;
} // end orderList
//////////////////////////////////////////////////////////////////////////////// //////////
//////////////////////////////////////////////////////////////////////////////// //////////
int main(void)
{
orderList();
sortArray();
return 0;
}
//////////////////////////////////////////////////////////////////////////////// //////////
//////////////////////////////////////////////////////////////////////////////// //////////
// is used in sortArray() to sort 2d array.
int compare(const void *a, const void *b) {
int x1 = *(const int*)a;
int x2 = *(const int*)b;
if (x1 > x2) return 1;
if (x1 < x2) return -1;
// x1 and x2 are equal; compare y's
int y1 = *(((const int*)a)+1);
int y2 = *(((const int*)b)+1);
if (y1 > y2) return 1;
if (y1 < y2) return -1;
return 0;
}
//////////////////////////////////////////////////////////////////////////////// //////////
//////////////////////////////////////////////////////////////////////////////// //////////
// sortArray function (here we want to implement the orderListArray[k][g]
// and run on that instead of predefined matrix which is included in the code
int sortArray(int b[], size_t size)
{ // begin sortArray
int matrix[][2] = {{8,6}, {4,2}, {1,0}, {4,8}, {2,4},
{4,3}, {1,2}, {2,2}, {8,3}, {5,5}};
printf("Original: ");
for (size_t i = 0; i < ARRAYSIZE(matrix); i++)
printf("(%d,%d) ", matrix[i][0], matrix[i][1]);
putchar('\n');
qsort(matrix, ARRAYSIZE(matrix), sizeof(*matrix), compare);
printf("Sorted : ");
for (size_t i = 0; i < ARRAYSIZE(matrix); i++)
printf("(%d,%d) ", matrix[i][0], matrix[i][1]);
putchar('\n');
return 0;
} // end sortArray
You have a bona fide 2D array. That's an array of arrays, so the elements are arrays, and therefore your compare function receives pointers to arrays as its arguments. Your comparison code is not actually wrong, but it would be a bit cleaner and clearer to acknowledge the correct types of the elements you are comparing:
int compare(const void *a, const void *b) {
const int (*x1)[2] = a;
const int (*x2)[2] = b;
if ((*x1)[0] > (*x2)[0]) return 1;
if ((*x1)[0] < (*x2)[0]) return -1;
if ((*x1)[1] > (*x2)[1]) return 1;
if ((*x1)[1] < (*x2)[1]) return -1;
return 0;
}
The main question seems to be represented by this code comment, however:
here we want to implement the orderListArray[k][g] and run on that instead of predefined matrix
It's not an especial problem for k to be an adjustable parameter, but it complicates matters greatly for g to be adjustable. To even declare your function requires either fudging types, or using a variable-length array. Either way, your function signature does not provide enough information. You must either know or assume both dimensions of your array, and you have only one parameter, size, to convey that information.
If you are assuming that the array to be sorted will be an array of pairs, as is matrix in your sample code, then simply write the function signature like so:
int sortArray(int b[][2], size_t size) // ...
and rely on the caller to provide the number of elements (pairs) via the size parameter. Then you could call qsort like so:
qsort(b, size, sizeof(*b), compare);
It's a lot messier if the matrix rows are variable length, because then you have to either dynamically choose a comparison function that is specific to the correct length, or generalize your comparison function and convey the row length to it by some means other than its arguments (thus, probably via a file-scope variable). Both of those approaches have significant drawbacks.
A third approach would be to rely on the caller of sortArray() to provide a suitable comparison function, but if you do that then you have to consider what value sortArray() is actually providing relative to calling qsort() directly.
I'm currently trying to write the code for a simple Quicksort in C, but I can't seem to understand C syntax and pointers. I'm used to coding in Java, so I'm a little confused on how to return int arrays, and what I'm doing wrong.
Here is my code right now, any help would be greatly appreciated.
#include <stdio.h>
#define MAX 100
int input[MAX];
int* QuickSort(int A[], int n);
int* combine (int first[], int pivot, int last[]);
//main method to run program
int main()
{
int i, n;
//read in input and store values in array named input
printf ("Enter several numbers separated by spaces or returnsand ended by Ctrl-D:\n");
for (n = 0; n < MAX && scanf("%d", &input[n]) != EOF; n++);
//runs QuickSort on the array
int new[n] = QuickSort(input, n);
printf("Here is your sorted array:\n");
//goes through sorted array to print values
for (i = 0; i < n; i++)
printf("%d\n", new[i]);
}
int* QuickSort(int A[], int n)
{
//if array has 1 value or is empty, automatically return
if (n <= 1)
return A;
int pivot = A[0];
int less[n/2];
int more[n/2];
int lesscount = 0;
int morecount = 0;
int i;
for (i = 1; i<n; i++)
{
if (A[i] <= pivot)
{
less[lesscount] = A[i];
lesscount++;
}
else if (A[i] > pivot)
{
more[morecount] = A[i];
morecount++;
}
}
int size = n/2;
return combine(QuickSort(less, size), pivot, QuickSort(more, size));
}
int* combine (int first[], int pivot, int last[])
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
int n;
for (n =0; n<firstsize; n++)
{
combined[n]= first[n];
}
combined[n]=pivot;
n++;
int m;
for (m =0; m<totalsize; m++)
{
combined[n] = last[m];
n++;
}
return combined;
}
The basics
A pointer is a memory address which you can dereference and access. It's very different from an object and is (mostly likely) just an 8-byte value. Whereas in Java you might be able to pass around objects (which do point to some memory somewhere), in C you must be a lot more careful about what memory you're pointing.
In particular, there is a difference between the stack and the heap. The stack is what your program uses to track local variables and will automatically allocate space. On the other hand, the heap is usually something you need to manage yourself. In particular, you won't get heap addresses unless you explicitly allocate it (i.e., with malloc). Why the distinction? Because the stack automatically allocates space, but also automatically deallocates space on function return.
Why does this apply to you?
Let's take a look on some of your functions:
int* combine (int first[], int pivot, int last[])
/* i.e., int* combine (int *first, int pivot, int *last) */
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
/* The rest of the code */
return combined;
}
You're returning combined, a stack allocated variable to whoever is calling your function. While doing this is "legal" in the strict sense, it's not correct because once you've returned from the function, the program will automatically deallocate the memory. This means you're probably getting some very confusing results and/or faults.
Now, how do you fix this?
In your case, quicksort doesn't need more space, just some clever manipulation of variables. Thus, you actually don't even need to use any of the sub arrays, nor do you need to return any arrays. The neat thing about pointers is that you get an address to memory. Thus, if you change that is pointed to (i.e., A[0] = x), then any other function which also knows about A will see that update.
And applied to quicksort?
Your initial implementation isn't quite correct either. Quicksort can be roughly broken down into two steps: partition and combine. When you partition, you want to separate all values less than a pivot value from all values greater than a pivot value. However, because you don't already know how many that is, assuming you'll have size/2 in each partition is going to cause you trouble.
For partition, you can use an in place iterative method. Something like this:
while index < end:
if A[index] < pivot:
index ++
else if A[index] > pivot:
swap(A[index], A[end])
end --
swap(pivot, A[index])
(There may be some off by one errors in the above.) The basic idea is that by keeping track of both a lower part and an upper part with two indices, you "add" the current value you're comparing against to the proper side (by moving to the next index, or swapping and decrementing the end). And by doing this in place, you don't need to deal with memory allocation.
The recursive step then becomes knowing where your sub-pieces are and recursively calling sort of each.