C 如何使用O(n)额外空间实现稳定的快速排序算法?

C 如何使用O(n)额外空间实现稳定的快速排序算法?,c,algorithm,sorting,quicksort,stable-sort,C,Algorithm,Sorting,Quicksort,Stable Sort,我可以使用一个额外的数组来执行稳定的快速排序,这与一般的快速排序算法不同。我知道如何随机选择pivot并进行相应的分区,但我不知道如何利用额外的数组使其稳定。想到的最简单的方法是将初始索引存储在数组中(1、2、3等),并在交换数据时交换它们 然后在比较中,如果两个元素相等,也比较它们的索引,从而使其稳定。正如Blindy和R所建议的,您可以只对索引进行排序,然后可以使用循环排序的变体对原始数组进行适当排序,其副作用是排序后的索引将重新排列为0到n-1。每次移动都会放置一个元素,因此时间复杂度为O

我可以使用一个额外的数组来执行稳定的快速排序,这与一般的快速排序算法不同。我知道如何随机选择pivot并进行相应的分区,但我不知道如何利用额外的数组使其稳定。

想到的最简单的方法是将初始索引存储在数组中(1、2、3等),并在交换数据时交换它们


然后在比较中,如果两个元素相等,也比较它们的索引,从而使其稳定。

正如Blindy和R所建议的,您可以只对索引进行排序,然后可以使用循环排序的变体对原始数组进行适当排序,其副作用是排序后的索引将重新排列为0到n-1。每次移动都会放置一个元素,因此时间复杂度为O(n)

void根据(整数数组[],大小索引[],大小长度)重新排序
{
尺寸i,j,k;
int t;
对于(i=0;i
什么是不稳定的快速排序?或者,不要修改数组中的数据,而是从创建指向原始数组元素的指针的新数组开始。然后简单地对指针数组进行排序,首先将指针与对象进行比较,然后将指针与对象进行比较,以打破平局。这是一种很好的技术,因为它可以对原始副本无法修改的数据进行排序。然而,如果你真的需要对原始数组进行重新排序,那么在最后这是一个额外的(稍微不重要的)步骤。是的,这是关于你将使用更多的东西,有序数组或原始映射。我假设,由于您正在进行排序,您将需要排序数组:)如果使用O(n)个额外空间,则可以使用合并排序,并且它已经是稳定的。如果要使用一个索引或指针数组,通常会使用两个索引或指针数组,但如果这些索引或指针像链表一样使用,其中每个索引或指针都指向下一个元素,则一个索引或指针数组就足够了。每个列表的末尾将是index=-1或pointer==null。局部变量用于跟踪合并算法中列表的开始,合并算法返回单个列表的开始值。出于各种技术原因,如果将此函数调整为采用
TYPE*数组、TYPE**指针、size\u t len
,则会更好,但它可能仍然应该遵循最佳实践,例如使用
size\u t
作为大小/索引,因为
int
可能会溢出。:-)使用指针更多的是一个技术细节(使用
qsort
API,您必须对指针进行排序,而不是索引,因为
qsort
没有额外的上下文参数可以传递给比较函数),但如果您将其用于您自己的排序,而您自己的排序确实有一种干净的方式来对索引进行排序。Uhg。如果没有明确的合同规定您对元素的大小/数量有限制,
size\u t
是唯一正确/安全的使用方法。令人沮丧的是,有人反对这样做,所以…:-(很好。我希望你没有觉得我在纠缠你。我只是希望示例代码可以安全地作为书面代码使用,或者有注释(在答案中或作为答案上的注释)反映了希望使用代码的人在使用代码之前应该解决的问题。在本例中,这不是问题。在X86-X64 64位模式中,使用32位无符号整数与64位无符号整数(size\t)相比,可能有一定的性能优势。此外,32位无符号整数将能够为大小为4 GB的数组编制索引,而4 GB的64位索引将占用32 GB的内存,加上数组的大小,因此从实用角度来看,大小\u t没有多大帮助,但它可能会使示例更清晰。
void reorder_according_to(int array[], size_t indices[], size_t len)  
{
size_t i, j, k;
int t;
    for(i = 0; i < len; i++){
        if(i != indices[i]){
            t = array[i];
            k = i;
            while(i != (j = indices[k])){
                array[k] = array[j];
                indices[k] = k;
                k = j;
            }
            array[k] = t;
            indices[k] = k;
        }
    }
}