4

I have an array: int a[6] = {3, 4, 1, 2, 5, 6} and I want to find the minimum and maximum element by using a pre-defined C function; is there one?

4
  • 5
    No there is no standard C function to do that. Commented Sep 21, 2021 at 5:49
  • 1
    you can sort the array using the qsort function (which is predefined) and then print the first/last element of the array whichever is the largest depending on the comparator function you have provided or make a function of your own - but a predefined function to do all this is not available. Commented Sep 21, 2021 at 6:06
  • this was quite a sneaky way, but it works the way I want, thanks. Commented Sep 21, 2021 at 7:10
  • 1
    C is not Python. Commented Sep 21, 2021 at 9:05

5 Answers 5

5

No, there isn't a minmax function in the standard library, but you could create one yourself.

Example:

#include <limits.h>
#include <stddef.h>
#include <stdio.h>

// a struct to hold the min and max result
typedef struct {
    int min;
    int max;
} mm;

// a function to find the min and max values
mm minmax(const int *arr, size_t len) {

    mm res = {INT_MAX, INT_MIN}; // start with min = INT_MAX, max = INT_MIN

    for(const int *end = arr + len; arr != end; ++arr) {
        if(*arr < res.min) res.min = *arr;
        if(*arr > res.max) res.max = *arr;
    }

    return res;
}

int main() {
    int a[6] = {3, 4, 1, 2, 5, 6};
    mm res = minmax(a, sizeof a / sizeof *a);
    printf("min: %d  max: %d\n", res.min, res.max);
}


This could be generalized into a function that can find the min and max elements in any type of array, much like the qsort function can sort an array of any type of elements that are comparable in a strict weak ordering kind of way.

#include <stddef.h>

// a struct to hold pointers to the min and max elements
typedef struct {
    const void *min;
    const void *max;
} mm;

// The signature of a function for comparing elements.
// Such a function should return
// -1 if the left hand side is less than the right
// +1 if the right hand side is greater than the left
//  0 otherwise
typedef int (*comp_func)(const void *, const void *);

// the minmax function now takes these arguments:
// in_arr : a "const void*" to the array
// count  : the number of elements
// size   : the size of an element
// compare: a pointer to a function capable of comparing two elements
mm minmax(const void *const in_arr, size_t count, size_t size, comp_func compare) {
    mm res = {0}; // both the min and max pointers are NULL

    if(count) {
        const char *cur = in_arr;
        const char *const end = cur + count * size;

        res.min = cur; // use the pointer to the first value as the pointer to min
        res.max = cur; // ...and max

        for(cur += size; cur != end; cur += size) {
            // call the compare function
            if(compare(cur, res.max) > 0) res.max = cur;
            else if(compare(cur, res.min) < 0) res.min = cur;
        }
    }
    return res;
}

With that minmax function in place, you could use it for an array of int or any type. You just have to supply a function to do the actual comparison of two elements.

Example:

#include <stdio.h>

int int_compare(const void *lhs, const void *rhs) {
    return *((int*)lhs) < *((int*)rhs) ? -1 :
           *((int*)lhs) > *((int*)rhs) ?  1 : 0;
}

int main() {
    int a[6] = {3, 4, 1, 2, 5, 6};
    mm res = minmax(a, sizeof a / sizeof *a, sizeof *a, int_compare);

    // dereference the min and max pointers to get the values:
    printf("min: %d  max: %d\n", *((int*)res.min), *(int*)res.max);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Or... we could keep it simple and not use pointers, which at a glance seems to yield much faster code. Also else if. godbolt.org/z/s47PE4E3q
@Lundin I think the else that you added to your version made up for most of the diff. godbolt.org/z/osbxnzshK The else only works if we initialize the result with the value in the first array element - similar to what I'm doing in the more generic minmax function that I just added.
3

No there is no standard C function. But You can do this yourself

int max = arr[0];
for (i = 1; i < n; i++)
    if (arr[i] > max)
        max = arr[i];

Whether it's big or small is obvious from the comparison inside the if. if >, is large. if <, is small

10 Comments

This wouldn't work with negative values. Better to set max to something like INT_MIN so any possible value for arr[i] is equal or larger.
Or just to the value of arr[0].
Sure, that works too. :-)
@Chris @sj95126 i solved problem. i equalized arr[0] to max
@ShubhamWadkar How would it become O(n^2). You can see that there' s one plain for loop. It's O(n) always. There are no solutions better than O(n) for finding min/max elements.
|
1

C99 contains math.h This has functions - fmin, fmax, fminl, fmaxl, fmaxf, fminf

#include <math.h>
double fmin( double x, double y );
float fminf( float x, float y );
long double fminl( long double x , long double y );

The fmin() functions return the value of the lesser argument.

#include <math.h>
double fmax( double x, double y );
float fmaxf( float x, float y );
long double fmaxl( long double x , long double y );

The fmax() functions return the value of the greater argument.

So, for the answer -

float max=0;
for (i = 0; i < n; i++)
        max = fmaxf (max, arr[i]);

2 Comments

but the thing is for loop is still there, I was looking for something with constant time. But thanks, this was also something new for me.
Initialising float max=0; causes the loop to fail for arrays that contain only negative values. Better initialize max to -INFINITY.
1

As Ted Lyngmo says, there isn't, but you can create your own. Note however that if you wish to compute both the minimum and maximum at the same time, you can reduce the total number of comparisons to 3n/2 in the worst case, using the following trick to process 2 elements using 3 comparisons:

typedef struct {
    int min;
    int max;
} MinMax;

MinMax minmax(const int *arr, size_t len) {
    MinMax res = {INT_MAX, INT_MIN};

    while (len >= 2) {
        int a = arr[0];
        int b = arr[1];
        if (a < b) {
           if (a < res.min) res.min = a;
           if (b > res.max) res.max = b;
        } else {
           if (b < res.min) res.min = b;
           if (a > res.max) res.max = a;
        }
        arr += 2;
        len -= 2;
    }

    if (len == 1) {
        if (*arr < res.min) res.min = *arr;
        if (*arr > res.max) res.max = *arr;
    }

    return res;
}

Comments

0

If you want constant time access to the minimum and maximum in an array, you can't have that. But depending on how the array is being populated, an array may be the wrong tool, or at least not the only tool to use. Binary heaps readily provide constant time access to the minimum or maximum (depending on whether it's a min heap or max heap) values.

So if you're reading input from the user, you can insert those values into a binary heap as you go and at any point the minimum or maximum value will be on top of the heap. You could even maintain two heaps and have both pieces of information simultaneously available. Maybe even insert into an array as well to maintain a record of insertion order.

Insertion has a higher cost, but read access has a much lower cost.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.