Home > Software engineering >  Finding Median of an Array
Finding Median of an Array

Time:10-10

I am trying to write a C program to find the median of an array, but the task requires to not sort the array. The current code I have works, but fails when there is a repeated number. I am struggling to find a way to account for this case. Any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>

int median_finder(int size, int* data) {
    int n1, n2;
    int count = 0;
    for (int t = 0; t < size; t   ) {
    int piv = data[t];
    int higher = 0;
    int lower = 0;
    int median;
    
    if (size % 2 != 0) {
        for (int j = 0; j < size; j  ) {
            if (piv < data[j]) {
                higher  ;
            } else if (piv > data[j]) {
                lower  ;
            } 
        }
        if (higher != 0 && lower == higher) {
            printf("MEDIAN: %d\n", piv);
            return 0;
        }
    } else {
        //int num = 0;
        for (int j = 0; j < size; j  ) {
            if (piv < data[j]) {
                higher  ;
            } else if (piv > data[j]) {
                lower  ;
            } 
        }
        if (higher != 0 && (lower == size/2 || higher == size/2)) {
        
        count  ;
        if (count == 1) {
            n1 = piv;
        } if (count == 2) {
            n2 = piv;
        }

        }
    } if (count == 2) {
        if (n1 > n2) {
            median = n2;
        } else {
            median = n1;
        }
        printf("Median: %d\n", median);
        return 0;
    }
    }
}

int main(int argc, char** argv) {
    int size = atoi(argv[1]);
    argv  ;
    argv  ;
    int data[size];
    for (int i = 0; i < size; i  ) {
        data[i] = atoi(argv[i]);
    }
    median_finder(size, data);
}

CodePudding user response:

The median for an unsorted array with possible duplicate values a of length n is the element with the value a[i] where half of the remaining elements (n-1)/2 (rounded down) are between less than (lt) or less than and equal (lt eq) to a[i]:

#include <assert.h>
#include <stdio.h>

int median(size_t n, int *a) {
    assert(n > 0);
    for(size_t i = 0; i < n; i  ) {
        size_t lt = 0;
        size_t eq = 0;
        for(size_t j = 0; j < n; j  ) {
            if(i == j) continue;
            if(a[j] < a[i]) lt  ;
            else if(a[j] == a[i]) eq  ;
        }
        if((n-1)/2 >= lt && (n-1)/2 <= lt   eq)
            return a[i];
    }
    assert(!"BUG");
}

// tap-like
void test(size_t test, int got, int expected) {
    printf("%sok %zu\n", got == expected ? "" : "not ", test);
    if(got != expected) {
        printf("  --\n"
               "  got: %d\n"
               "  expected: %d\n"
               "  ...\n", got, expected);
    }
}

int main(void) {
    struct {
        size_t n;
        int *a;
    } tests[] = {
        {1, (int []) {0}},
        {2, (int []) {0, 1}},
        {3, (int []) {-1, 0, 1}},
        {4, (int []) {-1, 0, 0, 1}},
    };
    for(int i = 0; i < sizeof tests / sizeof *tests; i  ) {
        test(i 1, median(tests[i].n, tests[i].a), 0);
    }
}

CodePudding user response:

Mr or Mrs. Roo4ma, you first need to find the size. Let's say the size is odd, and your array is [2,7,3,5,9]. Then as you can see, the median is 5. which is (size 1/2). You need to find the size/2'th element if the array size is even. For that, you can use "nested for" loops. An example:

#include<stdio.h>
#include<stdlib.h>
#define size 5
int main()
{
    int a[]={2,7,3,5,9},i,j,value;
    float median;
    for(i=0;i<size;i  ){
        value=0;
        for(j=0;j<size;j  ){
            if(a[j]>a[i])
                value  ;
        }
        if(value==(size/2)){
            median=a[i];
            break;
        }
    }
    printf("Median is %.1f",median);
    return 0;
}

But if the array size is even, we must adjust. An example is :

#include<stdio.h>
#include<stdlib.h>
#define size 6
int main()
{
    int a[]={2,3,7,3,5,9,8},i,j,value;
    float median;
    for(i=0;i<size;i  ){
        value=0;
        for(j=0;j<size;j  ){
            if(a[j]>a[i])
                value  ;
        }
        if(value==((size/2)-1) || value==(size/2)){
            median =a[i];
        }
    }
    median/=2;
    printf("Median is %.1f",median);
    return 0;
}

However, unfortunately, if the user enters the same numbers, there will be some errors in my second code. And I couldn't think of a way to solve this without sorting them first.

  • Related