如何在时间和空间复杂度的限制下交替对偶数和奇数进行排序?(C/C++)
How to sort even and odd numbers alternatively with the limit of time and space complexity?(C/C++)
给定一个像这样的integer array
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 的位置。稍加思考,您就可以证明您手头永远不会有负("已处理")值,最终您将在数组的空白处结束。
处理完所有值后,遍历数组一次以否定所有值,您将拥有所需的数组。我描述的算法的复杂性是线性的 - 每个值不会超过一次"在手边",并且您将迭代它不超过一次。
- 二叉排序树无法编译
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- 对字符串进行排序时,在c++中处理sort()
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 下面是排序算法O(n)吗
- std::sort()函数无法对向量的一部分进行排序
- shell排序中的交换和比较
- clang格式:禁用排序包含
- 显示错误输出的简单数组排序程序
- 为什么我的排序算法会更改数组值
- 试图在c++中对数字列表进行排序
- 如何在C++中对数组进行冒泡排序