简体   繁体   中英

The median of an unordered set

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.

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM