就地分区时该阵列可以或可以不包含所述枢轴元件枢轴、阵列、所述、不包含

2023-09-11 06:18:38 作者:那谁姐要你

有一个就地划分算法(在快速排序执行中使用的那种),不依赖枢轴元素是$ P $的psent数组中?

Is there an in-place partitioning algorithm (of the kind used in a Quicksort implementation) that does not rely on the pivot element being present in the array?

在换句话说,阵列元件必须排列顺序如下:

In other words, the array elements must be arranged in this order:

比枢轴元素少(如果有的话) 元素等于所述枢轴(如果有的话) 比枢轴元素更大(如果有的话)

它仍然必须返回索引中的支点元素(排序后),如果它恰好是present阵列中,或者一个特殊的值,如果没有;这可能是其中该元件可插入到保持顺序的索引的一的补的(如Java的标准返回值二进制搜索功能。)

It must still return the index (after sorting) of the pivot element if it happens to be present in the array, or a special value if not; This could be the one's complement of an index where the element could be inserted to maintain the order (like the return value of Java's standard binary search function.)

我见过的实现需要支点元素的索引将作为参数(或总是要在数组的开始。)不幸的是我不知道提前枢轴是否present在阵列(或其中它是数组中。)

The implementations I have seen require the index of the pivot element to be given as a parameter (or always to be at the start of the array.) Unfortunately I do not know in advance whether the pivot is present in the array (or where it is in the array.)

修改(在回答meriton's评论):我们也可以假设下列条件之一为真:

Edit (in reply to meriton's comments): We can also assume that one of the following conditions is true:

在该数组的长度为&lt; 2,或 在至少一种元素为&lt; =支点和的至少一种元素为> =支点 The array length is < 2, or At least one element is <= pivot and at least one element is >= pivot.

有可能是数组中重复的值(包括枢轴值的副本。)

There may be duplicate values in the array (including duplicates of the pivot value.)

推荐答案

这是一个有趣的问题。可以用一个单一的连续的穿过阵列做。在C#中,低于code例子。它假定整数数组名为 A 透视值。

This was an interesting problem. You can do it with a single sequential pass through the array. Code example in C#, below. It assumes an array of integers called a, and a pivot value.

// Skip initial items that are < pivot
int iInsert = 0;
while (iInsert < a.Length && a[iInsert] < pivot)
{
    ++iInsert;
}
// Skip items that are = pivot
int numPivot = 0;
while (iInsert < a.Length && a[iInsert] == pivot)
{
    ++iInsert;
    ++numPivot;
}

int iCurrent = iInsert;
// Items will be added AFTER iInsert.
// Note that iInsert can be -1.
--iInsert;
while (iCurrent < a.Length)
{
    if (a[iCurrent] < pivot)
    {
        if (numPivot == 0)
        {
            ++iInsert;
            int temp = a[iInsert];
            a[iInsert] = a[iCurrent];
            a[iCurrent] = temp;
        }
        else
        {
            ++iInsert;
            int temp = a[iInsert];
            a[iInsert - numPivot] = a[iCurrent];
            a[iCurrent] = temp;
            a[iInsert] = pivot;
        }
    }
    else if (a[iCurrent] == pivot)
    {
        ++iInsert;
        int temp = a[iInsert];
        a[iInsert] = pivot;
        a[iCurrent] = temp;
        ++numPivot;
    }
    ++iCurrent;
}

int firstPivot = iInsert - numPivot + 1;

有可能是一些优化的机会。

There are probably some optimization opportunities.

这个方法的有​​趣的事情是,你可以很容易地适应它来建立从输入数据流。你不会知道有多少项目来了。只要使用可以动态调整大小的列表。当最后一个项目进来,你的列表是按正确的顺序。

The interesting thing about this approach is that you could easily adapt it to build from a stream of incoming data. You wouldn't have to know how many items are coming. Just use a list that can be resized dynamically. When the last item comes in, your list is in the proper order.