对 4 个数字进行排序,进行少量比较

问题描述 投票:0回答:9

如何在 5 次比较中对 4 个数字进行排序?

algorithm sorting
9个回答
20
投票

将数字 {a,b,c,d} 分成 2 个集合 {a,b} {c,d}。 对这 2 组中的每一组进行排序,这样您就得到 (e,f) (g,h)。这是每组一次比较。

现在从前面选择最低的(比较 e,g)。现在这是三个比较。 从 (e, h) 或 (f, g) 中选择下一个最低值。那是四个。 比较最后两个元素(如果这两个元素来自同一集合,因此已经排序,您甚至可能不需要此步骤)。所以这是五个。


18
投票

伪代码:

function sortFour(a,b,c,d)
    if a < b
        low1 = a
        high1 = b
    else 
        low1 = b
        high1 = a

    if c < d
        low2 = c
        high2 = d
    else
        low2 = d
        high2 = c

    if low1 < low2
        lowest = low1
        middle1 = low2
    else
        lowest = low2
        middle1 = low1

    if high1 > high2
        highest = high1
        middle2 = high2
    else
        highest = high2
        middle2 = high1

    if middle1 < middle2
        return (lowest,middle1,middle2,highest)
    else
        return (lowest,middle2,middle1,highest)

14
投票

对于较少数量的输入,您可以生成最佳排序网络,以提供所需的最少比较次数。

您可以使用此页面

轻松生成它们

按升序对四个数字进行排序:

if(num1>num2) swap(&num1,&num2);
if(num3>num4) swap(&num3,&num4);
if(num1>num3) swap(&num1,&num3);
if(num2>num4) swap(&num2,&num4);
if(num2>num3) swap(&num2,&num3);

哪里

void swap(int *a,int *b)
{
   int temp = *a;
   *a = *b;
   *b = temp; 
}

或者您可以实现自己的交换过程而无需额外变量

(对于降序,只需将符号更改为< )


5
投票

这不需要额外的内存或交换操作,每次排序只需 5 次比较

def sort4_descending(a,b,c,d):
if a > b:
    if b > c:
        if d > b:
            if d > a:
                return [d, a, b, c]
            else:
                return [a, d, b, c]
        else:
            if d > c:
                return [a, b, d, c]
            else:
                return [a, b, c, d]
    else:
        if a > c:
            if d > c:
                if d > a:
                    return [d, a, c, b]
                else:
                    return [a, d, c, b]
            else:
                if d > b:
                    return [a, c, d, b]
                else:
                    return [a, c, b, d]
        else:
            if d > a:
                if d > c:
                    return [d, c, a, b]
                else:
                    return [c, d, a, b]
            else:
                if d > b:
                    return [c, a, d, b]
                else:
                    return [c, a, b, d]
else:
    if a > c:
        if d > a:
            if d > b:
                return [d, b, a, c]
            else:
                return [b, d, a, c]
        else:
            if d > c:
                return [b, a, d, c]
            else:
                return [b, a, c, d]
    else:
        if b > c:
            if d > c:
                if d > b:
                    return [d, b, c, a]
                else:
                    return [b, d, c, a]
            else:
                if d > a:
                    return [b, c, d, a]
                else:
                    return [b, c, a, d]
        else:
            if d > b:
                if d > c:
                    return [d, c, b, a]
                else:
                    return [c, d, b, a]
            else:
                if d > a:
                    return [c, b, d, a]
                else:
                    return [c, b, a, d]

4
投票

目标是通过 5 次比较对 4 个元素进行排序。

Comp 1--> 取任意两个元素 a,b 并比较它们,其最大值为 Max1,最小值为 Min1。

Comp 2--> 取另外两个元素 c,d 并比较它们,其最大值为 Max2,最小值为 Min2。

Comp 3-->比较Max1和Max2以获得最终的Max元素。

Comp 4--> 比较 Min1 和 Min2 以获得最终的 Min 元素。

Comp 5-->比较Comp 4和Comp 5中的失败者以获得他们的顺序。


2
投票

要在 5 次比较中对数字 ABCD 进行排序,请分别对 AB 和 CD 进行排序。这需要2次比较。现在像对字符串 AB 和 CD 进行合并排序一样调用合并。这需要 3,因为在第一次比较中,您将选择 A 或 C。您最终将合并 B 和 CD,或者 AB 和 D。这里您只需要 2 次比较,因为 AB 和 CD 都已排序。


2
投票

刚刚实现了一个无分支函数,该函数使用五次比较对四个元素进行排序。可以将其制作成C++模板来对任何类型进行排序。数据不受影响,

r
将包含按升序访问数组的索引。

// This function actually returns a char[4], using type punning to bypass C restrictions
int order4(int* values) {
  char r[4], h[2], m[2];
  h[0]=         values[1]<values[0];
  h[1]=2|(char)(values[3]<values[2]);  // 3210 -> {2<3}{0<1}
  r[0]=values[h[1]  ]<values[h[0]  ];
  r[3]=values[h[0]^1]<values[h[1]^1];  // {2<3}{0<1} -> 0<{21}<3
  m[0]=h[r[0]^1];
  m[1]=h[r[3]^1]^1;
  r[2]=values[m[1]]<values[m[0]];      // 0<{21}<3 -> 0<1<2<3
  r[0]=h[r[0]];
  r[1]=m[r[2]];
  r[2]=m[r[2]^1];
  r[3]=h[r[3]]^1;
  _ASSERT(((1<<r[0]) | (1<<r[1]) | (1<<r[2]) | (1<<r[3])) == 15); // Ensure that all elements present
  _ASSERT(values[r[0]]<=values[r[1]] && values[r[1]]<=values[r[2]] && values[r[2]]<=values[r[3]]); // Ensure that elements are sorted
  return *(int*)r;
}

1
投票
Alg. 3: compare five, this average = 4.28 (#8 average = 5), Similar as #8<br>
compare 01, sort -> 0,1<br>
compare 23, sort -> 2,3<br>
compare 12 -> return or next compare<br>
compare 02, sort -> 0,2<br>
compare 13, sort -> 1,3<br>
compare 12, sort -> 1,2
<code>    
function sort4CH(cmp,start,end,n)
{
var n     = typeof(n)    !=='undefined' ? n     : 1;
var cmp   = typeof(cmp)  !=='undefined' ? cmp   : sortCompare2;
var start = typeof(start)!=='undefined' ? start : 0;
var end   = typeof(end)  !=='undefined' ? end   : arr[n].length;
var count = end - start;
var pos = -1;
var i = start;
var c = [];
c[0] = cmp(arr[n][i+0],arr[n][i+1]);
c[1] = cmp(arr[n][i+2],arr[n][i+3]);
if (c[0]>0) {swap(n,i+0,i+1);}
if (c[1]>0) {swap(n,i+2,i+3);}
c[2] = cmp(arr[n][i+1],arr[n][i+2]);
if (!(c[2]>0)) {return n;}
c[3] = c[0]==0 ? 1 : cmp(arr[n][i+0],arr[n][i+2]);// c[2]
c[4] = c[1]==0 ? 1 : cmp(arr[n][i+1],arr[n][i+3]);// c[2]
if (c[3]>0) {swap(n,i+0,i+2);}
if (c[4]>0) {swap(n,i+1,i+3);}
c[5] = !(c[3]>0 && c[4]>0) ? 1 : (c[0]==0 || c[1]==0 ? -1 : cmp(arr[n]    [i+1],arr[n][i+2]));
if (c[5]>0) {swap(n,i+1,i+2);}
return n;
}
</code>

---------------------

Algoritmus: Insert sort sorted array 1-1, 2-2, 4-4, ... average = 3.96 = 1016/256 (average = 4.62 =1184/256 without previous cmp)
<code>    
// javascript arr[1] = [0,1,2,3]
function sort4DN2(cmp,start,end,n) // sort 4
{
var n     = typeof(n)    !=='undefined' ? n   : 1;
var cmp   = typeof(cmp)  !=='undefined' ? cmp   : sortCompare2;
var start = typeof(start)!=='undefined' ? start : 0;
var end   = typeof(end)  !=='undefined' ? end   : arr[n].length;
var count = end - start;
var pos = -1;
var i = start;
var c = [];
c[0] = cmp(arr[n][i+0],arr[n][i+1]);
c[1] = cmp(arr[n][i+2],arr[n][i+3]);
if (c[0]>0) {swap(n,i+0,i+1); c[0] = -1;}
if (c[1]>0) {swap(n,i+2,i+3); c[1] = -1;}
c[2] = cmp(arr[n][i+0],arr[n][i+2]);
//1234
if (c[2]>0)
    {
    //2013
    c[3] = c[1]==0 ? c[2] : cmp(arr[n][i+0],arr[n][i+3]);
    if (c[3]>0)
        {
        swap(n,i+0,i+2);
        swap(n,i+1,i+3);
        return n;
    }
    c[4] = c[0]==0 ? c[3] : (c[3]==0 ? 1 : cmp(arr[n][i+1],arr[n][i+3]));
    if (c[4]>0)
        {
        //2013->2031
        tmp = arr[n][i+0];
        arr[n][i+0] = arr[n][i+2];
        arr[n][i+2] = arr[n][i+3];
        arr[n][i+3] = arr[n][i+1];
        arr[n][i+1] = tmp;
        return n;
        }
    // 2013
    tmp = arr[n][i+2];
    arr[n][i+2] = arr[n][i+1];
    arr[n][i+1] = arr[n][i+0];
    arr[n][i+0] = tmp;
    return n;
    }
if (c[2]==0) {
    if (c[0]==0) {
        return n;
        }
    if (c[1]==0) {
        tmp = arr[n][i+1];
        arr[n][i+1] = arr[n][i+2];
        arr[n][i+2] = arr[n][i+3];
        arr[n][i+3] = tmp;
        return n;
        }
    }
c[3] = c[0]==0 ? c[2] : c[2]==0 ? -c[1] : cmp(arr[n][i+1],arr[n][i+2]);
if (c[3]>0)
    {
    c[4] = c[1]==0 ? c[3] : cmp(arr[n][i+1],arr[n][i+3]);
    if (c[4]>0)
        {
        swap(n,i+1,i+2);
        swap(n,i+2,i+3);
        return n;
        }
    swap(n,i+1,i+2);
    return n;
    }
return n;
}
</code>

------------

Algoritmus: Insert sort into middle (av. 4.07 = 1044/256 | 4.53 = 1160/256)
0<br>
1 insert into middle 0 -> [0,1] 01, 10<br>
2 insert into middle 01 -> [1,2] 021, 012 -> [0,2] 021, 201 or [null] 012<br>
3 insert into middle 012 -> [1,3] -> [1,0] or [2,3]...
<code>    
function sort4PA(cmp,start,end,n)
{
//arr[n] = [0,0,3,0];
var n     = typeof(n)    !=='undefined' ? n     : 1;
var cmp   = typeof(cmp)  !=='undefined' ? cmp   : sortCompare2;
var start = typeof(start)!=='undefined' ? start : 0;
var end   = typeof(end)  !=='undefined' ? end   : arr[n].length;
var count = end - start;
var tmp = 0;
var i = start;
var c = [];
c[0] = cmp(arr[n][i+0],arr[n][i+1]);
if (c[0]>0) {swap(n,i+0,i+1); c[0] = -1;} //10->01
c[1] = cmp(arr[n][i+1],arr[n][i+2]);
if (c[1]>0) {   //0-1 2
    c[2] = c[0]==0 ? c[1] : cmp(arr[n][i+0],arr[n][i+2]);
    if (c[2]>0) {   //-01 2
        c[3] = cmp(arr[n][i+0],arr[n][i+3]);
        if (c[3]>0) {//2301
            c[4] = cmp(arr[n][i+2],arr[n][i+3]);
            if (c[4]>0) { //0123 -> 3201
                tmp = arr[n][0];
                arr[n][0]=arr[n][3];
                arr[n][3]=arr[n][1];
                arr[n][1]=arr[n][2];
                arr[n][2]=tmp;
                return n;
                }
            swap(n,i+0,i+2);
            swap(n,i+1,i+3);
            return n;
            }
        // 2031
        c[4] = c[0]==0 ? c[3] : cmp(arr[n][i+1],arr[n][i+3]);
        if (c[4]>0) {   //2031
            tmp = arr[n][0];
            arr[n][0]=arr[n][2];
            arr[n][2]=arr[n][3];
            arr[n][3]=arr[n][1];
            arr[n][1]=tmp;
            return n;
            }
        tmp = arr[n][0];
        arr[n][0]=arr[n][2];
        arr[n][2]=arr[n][1];
        arr[n][1]=tmp;
        return n;
        }
    //0-1 2
    c[3] = cmp(arr[n][i+2],arr[n][i+3]);
    if (c[3]>0) {
        c[4] = c[2]==0 ? c[3] : cmp(arr[n][i+0],arr[n][i+3]);
        if (c[4]>0) {//3021
            tmp = arr[n][0];
            arr[n][0]=arr[n][3];
            arr[n][3]=arr[n][1];
            arr[n][1]=tmp;
            return n;
            }
        //0321
        swap(n,i+1,i+3);
        return n;
        }
    // 0-1 23
    c[4] = c[3]==0 ? c[1] : cmp(arr[n][i+1],arr[n][i+3]);
    if (c[4]>0) {   //0231
        tmp = arr[n][1];
        arr[n][1]=arr[n][2];
        arr[n][2]=arr[n][3];
        arr[n][3]=tmp;
        return n;
        }
    //0213
    swap(n,i+1,i+2);
    return n;
    }
c[2] = cmp(arr[n][i+1],arr[n][i+3]);
if (c[2]>0) {
    c[3] = c[0]==0 ? c[2] : cmp(arr[n][i+0],arr[n][i+3]);
    if (c[3]>0) {
        // 3012
        tmp = arr[n][0];
        arr[n][0]=arr[n][3];
        arr[n][3]=arr[n][2];
        arr[n][2]=arr[n][1];
        arr[n][1]=tmp;
        return n;
        }
    // 0312
    tmp = arr[n][1];
    arr[n][1]=arr[n][3];
    arr[n][3]=arr[n][2];
    arr[n][2]=tmp;
    return n;
    }
c[3] = c[1]==0 ? c[2] : c[2]==0 ? -c[1] : cmp(arr[n][i+2],arr[n][i+3]);
if (c[3]>0) {
    swap(n,i+2,i+3);
    }
return n;
}
</code>

0
投票

比较 Python 实现,Siddarth 和 Trott 的解决方案虽然排序顺序不同,但执行时间相似。 Daw 的建议(转换为 Python)在测试中稍微慢了 0.0000001 秒,尽管所有这些选项都执行得很快。我的替代解决方案使用 5 或 6 次比较,75% 的情况使用 5 次比较。虽然它通常比前三个慢,但它通常优于插入排序。:

    permDict = {
    ''     : lambda a: a,                                                                   
    '12345': lambda a: [a[3],a[2], a[1], a[0]],                                             
    '5'    : lambda a: [a[0],a[2], a[1], a[3]],                                             
    '1234' : lambda a: [a[3],a[1], a[2], a[0]],                                             
    '2'    : lambda a: [a[0],a[1], a[3], a[2]],                                             
    '2345' : lambda a: [a[3],a[2], a[0], a[1]],                                             
    '45'   : lambda a: [a[0],a[2], a[3], a[1]],                                             
    '124'  : lambda a: [a[3],a[1], a[0], a[2]],                                             
    '245'  : lambda a: [a[0],a[3], a[2], a[1]] if a[0] < a[3] else [a[3],a[0], a[2], a[1]], 
    '24'   : lambda a: [a[3],a[0], a[1], a[2]] if a[3] < a[0] else [a[0],a[3], a[1], a[2]], 
    '1'    : lambda a: [a[1],a[0], a[2], a[3]],                                             
    '1345' : lambda a: [a[2],a[3], a[1], a[0]],                                             
    '12'   : lambda a: [a[1],a[0], a[3], a[2]] if a[0] < a[3] else [a[1],a[3], a[0], a[2]], 
    '345'  : lambda a: [a[2],a[3], a[0], a[1]] if a[0] < a[3] else [a[2],a[0], a[3], a[1]], 
    '35'   : lambda a: [a[2],a[0], a[1], a[3]],                                             
    '123'  : lambda a: [a[1],a[3], a[2], a[0]],                                             
    '13'   : lambda a: [a[1],a[2], a[0], a[3]] if a[0] < a[3] else [a[1],a[2], a[3], a[0]], 
    '135'  : lambda a: [a[2],a[1], a[0], a[3]] if a[0] < a[3] else [a[2],a[1], a[3], a[0]], 
}

def permSort(arr):
    comp = ""
    if arr[0] > arr[1]:
        comp += "1"
    if arr[2] > arr[3]:
        comp += "2" 
    if arr[0] > arr[2]:
        comp += "3"
    if arr[1] > arr[3]:
        comp += "4"
    if arr[1] > arr[2]:
        comp += "5"
    return permDict[comp](arr)
© www.soinside.com 2019 - 2024. All rights reserved.