替换选择排序

时间:2016-12-17 12:37:15

标签: java sorting replace heap

所以我一直在努力实现这个算法,但我不确定从哪里开始。基本上从我的理解,你可以通过两种方式实现它,通过排序顶级是最小值(minHeap)或顶级是最大值(maxHeap)。我搜索了很多关于这两种方式中的任何一种,我无法掌握如何实际实现它。我不会理解这个想法我会说,有人可以解释一下这是如何工作的吗?就像minHeap应该如何工作,或者maxHeap一样。 提前谢谢!

1 个答案:

答案 0 :(得分:1)

我假设您对数组中的二进制堆实现有基本的了解。

假设您有一个整数数组,您希望按升序排序。一种方法是重新排列数组中的项目,以便它们形成最大堆。

然后,将顶部项(数组中的最大项)与堆中的最后一项交换,将堆计数减少1,并将项从上到下筛选到堆中的新位置。最后,数组中的第一项将是下一个最大项。您为每个项重复该操作,并对您的数组进行排序。

我们举一个小例子。给定数组[4,7,6,1,3,5,2],您可以使用Floyd的算法将它们重新排列到堆中。

for (int i = array.length/2; i >= 0; i--)
{
    siftDown(i);
}

这是O(n)操作。

完成后,数组将安排在二进制堆中。在这种情况下,堆将是[7,4,6,1,3,5,2]或:

       7
     4   6
    1 3 5 2

所以,我们将根项与最后一项交换,给我们:[2,4,6,1,3,5,7]。我们减少计数并将其筛选到适当的位置,给出:[6,4,5,1,3,2,7]或堆表示:

       6
     4   5
    1 3 2

(我省略了7,因为我们减少了计数。但它仍然在数组的末尾。)

再次,将顶部项目与堆中的最后一项交换:[2,4,5,1,3,6,7],减少计数,然后进行筛选:[5,4,2,1,3,6,7]

      5
    4   2
   1 3

如果继续对堆中剩余的五个项目进行处理,最终会得到一个已排序的数组。

这个代码非常简单:

int count = array.length-1;
while (count > 0)
{
    swap(array[0], array[count]);
    --count;
    siftDown(0);
}

如果要进行降序排序,可以使用max-heap执行上述操作,然后反转数组(O(1)操作),也可以构建一个min-heap来启动。

siftDown方法只是按照二进制堆构造的规则将项目移动到适当的位置:

void siftDown(int index)
{
    // Left child is at index*2+1. Right child is at index*2+2;
    while (true)
    {
        // first find the largest child
        int largestChild = index*2+1;
        // if left child is larger than count, then done
        if (largestChild >= count)
        {
            break;
        }
        // compare with right child
        if (largestChild+1 < count && array[largestChild] < array[largestChild+1])
        {
            ++largestChild;
        }

        // If item is smaller than the largest child, then swap and continue.
        if (array[index] < array[largestChild])
        {
            swap(array[index], array[largestChild]);
            index = largestChild;
        }
        else
        {
            break;
        }
}