用很少的比较对4号进行排序

时间:2011-05-26 21:33:55

标签: algorithm sorting

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

8 个答案:

答案 0 :(得分:16)

将数字{a,b,c,d}分成2组{a,b} {c,d}。 订购这两套中的每一套,你得到(e,f)(g,h)。这是每组的一次比较。

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

答案 1 :(得分:10)

伪代码:

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)

答案 2 :(得分:2)

要在5次比较中对ABCD编号进行排序,请分别对AB和CD进行排序。这需要2次比较。现在在字符串AB和CD上调用合并排序中的合并。这需要3,因为在第一次比较中你要么选择A或C.你最终会有B和CD合并或AB和D.而这里你需要进行2次比较,因为AB和CD已经分类了。 / p>

答案 3 :(得分: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>

答案 4 :(得分:1)

这不需要额外的内存或交换操作,每次只需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]

答案 5 :(得分:1)

对于较少数量的输入,您可以生成最佳排序网络,从而提供必要的最小比较次数。

您可以使用this page

轻松生成它们

按升序排序四个数字:

//Set up Total column
                for (var i = 0; i < ds.Tables["tblTotal"].Rows.Count; i++)
                {
                    //force empty string to prevent null errors
                    var rowName = string.IsNullOrEmpty(ds.Tables["tblTotal"].Rows[i]["Name"].ToString()) ? "" : ds.Tables["tblTotal"].Rows[i]["Name"];
                    var rowAddress = string.IsNullOrEmpty(ds.Tables["tblTotal"].Rows[i]["Address"].ToString()) ? "" : ds.Tables["tblTotal"].Rows[i]["Address"];
                    var rowId = string.IsNullOrEmpty(ds.Tables["tblTotal"].Rows[i]["ID"].ToString()) ? "" : ds.Tables["tblTotal"].Rows[i]["ID"];
                    var rowGuid = string.IsNullOrEmpty(ds.Tables["tblTotal"].Rows[i]["CustGUID"].ToString()) ? "" : ds.Tables["tblTotal"].Rows[i]["CustGUID"];
                    var rowDob = string.IsNullOrEmpty(ds.Tables["tblTotal"].Rows[i]["DateOfBirth"].ToString()) ? "" : ds.Tables["tblTotal"].Rows[i]["DateOfBirth"];
                    var rowUrl = startURL(Request["isadmin"] != "0", rowGuid.ToString());

                    //write out this row
                    htmlTotal.Append("<tr>");
                    htmlTotal.Append(@"<td>");
                    htmlTotal.Append(@"<a href=" + rowUrl + "> " + rowName + @"</a>");
                    htmlTotal.Append(@"</td>");
                    htmlTotal.Append(@"<td>");
                    htmlTotal.Append(@"<a href=" + rowUrl + "> " + rowAddress + @"</a>");
                    htmlTotal.Append(@"</td>");
                    htmlTotal.Append(@"<td>");
                    htmlTotal.Append(@"<a href=" + rowUrl + "> " + rowId + @"</a>");
                    htmlTotal.Append(@"</td>");
                    htmlTotal.Append(@"<td>");
                    htmlTotal.Append(@"<a href=" + rowUrl + "> " + rowDob + @"</a>");
                    htmlTotal.Append(@"</td>");
                    htmlTotal.Append(@"<td>");
                    htmlTotal.Append(@"<input type=""checkbox"" Enabled=""true"" name=""chkTotal" + i + @""" value=""" + "VAL" + i + @""">"); //email check box
                    htmlTotal.Append(@"</td>");
                    htmlTotal.Append("</tr>");
                }
            }
            else
            {
                htmlTotal.Append("<tr>");
                htmlTotal.Append("<td align='center' colspan='6'>No Results Found</td>");
                htmlTotal.Append("</tr>");
                htmlTotal.Append("</table>");
                htmlTotalCount.Append("0");
            }

            //link the page dynamic control back to the html string builder code
            DBTotal.Controls.Add(new Literal { Text = htmlTotal.ToString() });
            DBTotalCount.Controls.Add(new Literal { Text = totalRecords.ToString() });
            htmlTotalCount.Append(" of " + totalRecords + " results");
            DBTotalCount2.Controls.Add(new Literal { Text = htmlTotalCount.ToString() });
            TotalPagination.Controls.Add(new Literal { Text = htmlTotalPagination.ToString() });

其中

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);

或者您可以在没有额外变量的情况下实现自己的交换过程

(对于降序,只需将符号更改为&lt;)

答案 6 :(得分:0)

目标是在5个比较中对4个元素进行排序。

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

比较2->将其他两个元素说成c,d并对其进行比较,其最大值为Max2,最小值为Min2。

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

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

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

答案 7 :(得分:0)

仅实现了一个无分支功能,该功能使用五个比较对四个元素进行排序。可以将其制成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;
}