用4个选项对数组进行排序的算法

时间:2014-04-01 11:29:44

标签: java algorithm sorting

我被赋予了一个任务来对一个填充了(非负)整数的数组进行排序。

应对它们进行排序,使输出的顺序如下:

  • 其余部分除以4的数字为0
  • 其余部分除以4的数字为1
  • 其余部分除以4的数字为2
  • 其余部分除以4的数字为3

我尝试编写一个应该在O(n)下运行的简单算法(任务是有效地编写代码)。

但是我觉得它很乱,有些情况不起作用(例如当我尝试一个阵列时,前几个数字的余数为3)。

有关如何修复它的建议或更好的方法吗?

public static void sortByFour(int[] arr)
{
    int zeroR = -1, oneR = 0, twoR = arr.length-1, threeR = arr.length;

    do
    {
        if (arr[oneR]%4==1)
         oneR++;
        else if (arr[oneR]%4==0)
        {
            zeroR++;
            int temp = arr[oneR];
            arr[oneR] = arr[zeroR];
            arr[zeroR] = temp;
            oneR++;
        }
        else if (arr[oneR]%4==2)
        {
            twoR--;
            int temp = arr[oneR];
            arr[oneR] = arr[twoR];
            arr[twoR] = temp;
        }
        else if (arr[oneR]%4==3)
        {
            threeR--;
            int temp = arr[oneR];
            arr[oneR] = arr[threeR];
            arr[threeR] = temp;
        }
    } while (oneR < threeR && oneR < twoR);
}

1 个答案:

答案 0 :(得分:4)

bucket sort可以帮到你。请注意,您可以通过循环4次(每个提醒一次)来克服桶排序的O(n)额外空间因子,类似于(类似Java的伪代码):

final int REMINDER = 4; //4 because you use %4
int curr = -1;
for (int r = 0; r < REMINDER ; r++) { 
   for (int i = curr + 1; i < arr.length; i++) { 
       if (arr[i] % REMINDER  == r) { 
          //swap elements:
          int temp = arr[i];;
          arr[i] = arr[++curr];
          arr[curr] = temp;
       }
   }
}

这个想法是“记住”你最后设置元素的位置,并迭代数组4次,并将带有匹配提醒的元素交换到所需的位置(你记得)。

复杂性仍为O(n)O(1)额外空间。

另一个是O(n)(但更好的常量)O(n)空间的时间是使用经典的桶排序,单个传递根据所需的提醒将所有元素存储在4个不同的列表中,在第二遍 - 在这4个列表中,根据所需顺序用原始数组填充元素。