1

I am a compsci student, and I received the following problem in Analysis & Design II class:

The median of an unordered set is an element such that the number of elements less than the median is within one of the number of elements that are greater, assuming no ties.

(a) Write an algorithm thst find the median of 3 distincts values a, b, c.

(b) Determine the number of comparisons your algorithm does in the average case and in the worst case.

From the little I searched and learned, it seems like this is called finding the kth element of an unsorted array, or finding the median of medians?

However, we have not learned quicksort yet, and all I could find seems way more complicated than what is asked of me here. That said, I am not entirely sure I understand the definition presented in this problem. Also, does finding the median of 3 distinct values a, b, c means finding the median of a set of size 3?

I am not necessarily looking for an answer. Just simple explanations or clarifications. Thanks.


Attempt #1

(a) Following templatetypedef's advice, I have came up with this naïve algorithm to solve this:

medianOf(int a, int b, int c)
    if a < b
        if a > c
            return a
    else //a > b
        if a < c
            return a    

    if b < c
        if b > a
            return b
    else //b > c
        if b < a
            return b

    if c < a
        if c > b
            return c
    else //c > a
        if c < b
            return c

I am aware it's very naïve and ugly, but I couldn't come up with a better solution and it already took too much of my time.

(b) It seems like the best case is when c < a < b with 2 comparisons, and the worst case is when a < c < b with 9 comparisons? So, the average would be (2+9)/2 which is 5 or 6 comparisons?

Or am I being naïve now?


Attempt #2

(a) Ok, so, following thang's advice, I tried really hard to minimize the number of comparisons to 3. Mathematically speaking, I understand your point. It is enough to check a<b, b<c, a<c and deduct the rest of the states from it, but I could not find a way to code it... This is my best attempt:

medianOf(int a, int b, int c)
    if a < b                                  1
        if c < a                              1
            return a    //c < a < b
        else  // a < b && a < c
            if b < c                          1
                return b    //a < b < c
            else
                return c    //a < c < b    

    else    //a > b
        if c > a                              1
            return a    //c > a > b
        else //a > b && a > c
            if b > c                          1
                return b    //a > b > c
            else                
                return c    //a > c > b

I don't see how I can do any better than this:

(b) Best case: 1 comparison. Average case: 5/2 = 2 to 3 comparisons. Worst case: 5 comparisons.

Any better?


Final Solution

Thanks to thang, and with a lot of effort, I finally got it. My last algorithm is correct, but my counting was wrong.

(b) Best case: 2 comparisons. Average case: 2 comparisons. Worst case: 3 comparisons.

Gil Dekel
  • 355
  • 4
  • 15
  • It seems to me that it means that you should find the median of a set of 3 elements. – kraskevich Feb 18 '15 at 20:54
  • your implementation is sloppy. you shouldn't need 5 or 6 comparisons ever. you're making the same comparison multiple times in some cases. there are only 3 possible comparisons you can make. – thang Feb 18 '15 at 23:31
  • In your code, notice that the first thing you do is "if a < b", and then inside "if b < c", you're comparing b > a, which is redundant. Here's a hint: think about how many ways a, b, c can be arranged in sorted order... – thang Feb 18 '15 at 23:34
  • I don't know, I can't see it. Here's what I got: there are 1*2*3 = 3! = 6 different ways to arrange a, b, and c in ordered sets. I was able to reduce the algorithm to 6 comparisons.. but I can't see how it can be done with 3. it means that 1 comparison should be able to rule out 2 sets. how? – Gil Dekel Feb 19 '15 at 00:36
  • @thang the second attempt is the closest I could get to what you're describing (see my edited question). With no way of saving variables' states, and using only comparisons, I simply cannot see any other way than with a minimum of five comparisons. It seems to me that it is inevitable to repeat one or two comparisons.. – Gil Dekel Feb 19 '15 at 04:12
  • 1
    You got it this time. Count again. At most 3 comparisons get executed everytime the function is called. – thang Feb 19 '15 at 04:18
  • Holy wakamo.. You're right! Thank you! This is not the first time you help me like this. I appriciate it. – Gil Dekel Feb 19 '15 at 04:30

2 Answers2

4

Fortunately, I think you're overthinking this. :-) Think of it this way - could you implement this function?

 int medianOf(int a, int b, int c) {
      ...
 }

You don't have to worry about finding the medians of arbitrary sets. Just find the median of the three inputs.

Once you've done that, look at the comparisons you make and think about the best-case, worst-case, and average-case number of comparisons. You can directly count how many comparisons you're making because your code should be pretty short.

The median-of-medians technique you're thinking of is for the more general case where you have an arbitrary number of elements and want to take the median of all of them. It's definitely more complex than this, but that doesn't seem to be what you're being asked to do.

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • Ok, this is very encouraging! can you perhaps shed some light on the definition tho? "an element such that the number of elements less than the median is within one of the number of elements that are greater, assuming no ties." I think the most confusing part is _one of the number of elements that are greater"... – Gil Dekel Feb 18 '15 at 20:59
  • @GilDekel The median element is the one that, were you to sort the elements into increasing order, would be in the middle. The median of 2, 1, and 3, for example, is 2. – templatetypedef Feb 18 '15 at 21:01
  • Well, I know the definition of what a median is: the middle number of a set of odd length, and the average of the two middle values of a set of even length. Is that what this definition is trying to say? :/ – Gil Dekel Feb 18 '15 at 21:03
  • @GilDekel Yep! If you have the median, the number of elements smaller than it (S) will be off by at most one from the number of elements greater than it (G), so |S - G| <= 1. It's a different way of thinking about the median that doesn't require sorting. – templatetypedef Feb 18 '15 at 21:06
  • nice! I have edited my question with an attempt. Would appreciate it if you could have a look and tell me if I'm close or stoopid. – Gil Dekel Feb 18 '15 at 22:08
  • @GilDekel If you now have an attempt, you should probably post that as a separate question, since it's a very different question than the one you originally posted. – templatetypedef Feb 18 '15 at 22:15
0

Hint:

If a <= b and b <= c, then b is the median.

If a <= b and b > c and c >=a, then c is the median.

If a<=b and b > c and c < a, then a is the median.

If a >= b and b >= c, then b is the median.

If a >= b and b < c and a >= c, then c is the median.

If a >=b and b < c and a < c, then a is the median.

You can code this up in nested if/else statements, such that you either execute 2 or 3 comparisons before you return an answer. The only question is the worst case, the best case, and the average case for the number of comparisons. For average case, you will have probably have to assume that all 3 numbers are distinct (but in random order), otherwise the "equals" case can change the average number of comparisons depending on how often it happens.

user2566092
  • 4,631
  • 15
  • 20