C++ 如何在时间和空间复杂度的限制下交替排序奇偶数?(C/C+;+;)

C++ 如何在时间和空间复杂度的限制下交替排序奇偶数?(C/C+;+;),c++,algorithm,sorting,time-complexity,C++,Algorithm,Sorting,Time Complexity,给定一个整数数组 int numbers[8]={1, 3, 5, 7, 8, 6, 4, 2}; 前面数组中的一半是奇数,其余的(等量数) 我们是平等的。奇数按升序排列,偶数部分按降序排列。排序后,数字的顺序不能更改 我如何以时间复杂度小于O(n^2)和空间复杂度O(1)的方式对它们进行交替排序 对于这个例子,结果将是:{1,8,3,6,5,4,7,2} 我不能使用外部阵列存储,但可以接受临时变量。 我尝试使用两个指针(oddPtr,evenPtr)分别指向奇数和偶数,并移动evenPtr将

给定一个
整数数组

int numbers[8]={1, 3, 5, 7, 8, 6, 4, 2};
前面数组中的一半是奇数,其余的(等量数) 我们是平等的。奇数按升序排列,偶数部分按降序排列。排序后,数字的顺序不能更改

我如何以时间复杂度小于
O(n^2)
和空间复杂度
O(1)
的方式对它们进行交替排序

对于这个例子,结果将是:
{1,8,3,6,5,4,7,2}

我不能使用外部阵列存储,但可以接受临时变量。

我尝试使用两个指针(
oddPtr,evenPtr
)分别指向奇数和偶数,并移动
evenPtr
将偶数插入奇数的中间。(类似插入排序)
但是它需要
O(n^2)


更新

根据Dukeling的评论,我意识到我提出的解决方案实际上不是线性的,而是线性的,甚至更糟——你无法控制它是否需要额外的内存。在我第二次思考时,我意识到您对阵列了解很多,您可以实现一个更具体但可能更简单的解决方案

我将假设数组中的所有值都是正值。我需要这个,这样我就可以使用负值作为“已处理”标志。我的想法如下-从左到右迭代数组。对于已处理的每个元素(即其值为负值),只需继续处理下一个元素即可。否则,您将得到一个常量公式,其中是该元素应位于的位置:

  • 如果该值为奇数且其索引为
    i
    ,则应移动到
    i*2
  • 如果该值为偶数且其索引为
    i
    ,则应移动到
    (i-n/2)*2+1
将此值存储到临时数组中,并使数组的当前索引处的值为0。现在,直到我们“手头上”的值不是零的位置,将其与保持在我们应该根据上面的公式放置它的位置的值交换。此外,当您将值放在手边时,将其取反以“将其标记为已处理”。现在我们有了一个新的值“在手”,我们再次根据上面的公式计算它应该去哪里。我们继续移动值,直到“手头上的”值应移到0的位置。只要稍加考虑,您就可以证明,您手头永远不会有一个负值(“已处理”)值,并且最终将在数组的空白处结束


处理完所有值后,在数组上迭代一次以对所有值求反,就得到了所需的数组。我所描述的算法的复杂性是线性的——每个值都不会超过一次“在手边”,并且您将对其进行迭代

std::sort
实现的普通快速排序quciksort的时间复杂度为O(n^2)。@Stallman std::sort的复杂度为
O(n*log(n))
它使用introsort-quickosrt与其他几种算法的组合。在最坏的情况下,快速排序的复杂度是O(n^2)。但它要求我即使在最坏的情况下也要避免O(n^2)。此链接可能有一个解决方案+1,但我现在想知道,如果范围是根据不同的标准排序的,那么
inplace\u merge
是否可以工作。就地合并如何工作?我无法将原始数组拆分为两部分,因为它需要额外的内存。@Stallman您必须使用比较
运算符的替代实现来实现您自己的整数比较器实际上,由于您只有恒定的额外空间,因此它是线性的(根据您提供的链接)。我认为这更多的是一个算法问题,即“使用这个库函数”不是一个特别好的答案,除非你也解释了函数是如何工作的。@Dukeling你的笔记绝对正确。我已经完全改变了我的答案,现在我相信它符合OP的需要。另外,我学到了一个新东西——我一直认为就地合并在所有情况下都是线性的。