How to sort three variables using at most two swaps?

后端 未结 10 1426
终归单人心
终归单人心 2020-12-10 00:56

The following algorithm can sort three variables x, y and z of type K which are comparable using operator<

相关标签:
10条回答
  • 2020-12-10 01:40
    void sort(int& a, int& b, int& c)
    {
       swap(a, min(a, min(b, c)));
       swap(b, min(b, c));
    }
    

    2 swaps, 3 comparisons.

    0 讨论(0)
  • 2020-12-10 01:42

    Cool question :)

    If assembly is available to you, and the values fit in a register, then you can probably do it extremely fast by just loading them into registers and doing a few compares, jumping to the right scenario to put the values back. Maybe your compiler makes this optimization already.

    Either way, if performance is your goal, take a look at the generated machine code and optimize there. For such a small algorithm that's where you can squeeze performance out of.

    0 讨论(0)
  • 2020-12-10 01:43

    Find the minimum value and swap it with the first value. Find the second minimum and swap it with the second value. Two swaps at most.

    This is basically selection sort, which will perform at most n - 1 swaps.

    0 讨论(0)
  • 2020-12-10 01:43

    If you don't do it in place, you can perform it without any swaps.

    0 讨论(0)
  • 2020-12-10 01:49

    I recently had to solve a similar problem - sort three values efficiently. You concentrate on swap-operations in your question. If performance is what you are looking for, concentrate on the comparison operations and branches! When sorting such a "tiny" array with just three values, a good idea is to consider using additional storage, which is appropriate for so few values. I came up with something like a specialized "merge sort" (see code below).

    Just as tenfour suggests, I looked at the assembly, and the code below compiles down to a compact inline set of CPU-register operations, and is extremely fast. The additional variable "arr12" is also stored in the CPU-registers. The sorting requires two or three comparison operations. The function can easily be converted to a template (not given here for clarity).

    inline void sort3_descending( double * arr )
    {
        double  arr12[ 2 ];
    
        // sort first two values
        if( arr[ 0 ] > arr[ 1 ] )
        {
            arr12[ 0 ] = arr[ 0 ];
            arr12[ 1 ] = arr[ 1 ];
        } // if
        else
        {
            arr12[ 0 ] = arr[ 1 ];
            arr12[ 1 ] = arr[ 0 ];
        } // else
    
        // decide where to put arr12 and the third original value arr[ 3 ]
        if( arr12[ 1 ] > arr[ 2 ] )
        {
            arr[ 0 ] = arr12[ 0 ];
            arr[ 1 ] = arr12[ 1 ];
        } // if
        else if( arr[ 2 ] > arr12[ 0 ] )
        {
            arr[ 0 ] = arr  [ 2 ];
            arr[ 1 ] = arr12[ 0 ];
            arr[ 2 ] = arr12[ 1 ];
        } // if
        else
        {
            arr[ 0 ] = arr12[ 0 ];
            arr[ 1 ] = arr  [ 2 ];
            arr[ 2 ] = arr12[ 1 ];
        } // else
    }
    
    0 讨论(0)
  • 2020-12-10 01:53

    I think what you want is to find the optimal swap in each step instead of just a valid swap. To do that, just find the greatest difference between an element and an element later in the list and swap those. In a 3-tuple, there are three possible swaps, 1-3, 1-2, and 2-3. At each step find the max difference among these three swaps and do that. Pretty sure that gives two swaps in the worst case for 3 elements. Only really makes sense if swapping is relatively expensive compared to comparing elements, otherwise probably not worth the additional analysis upfront.

    0 讨论(0)
提交回复
热议问题