简体   繁体   English

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

[英]How to sort even and odd numbers alternatively with the limit of time and space complexity?(C/C++)

Given a integer array like 给定一个integer array

int numbers[8]={1, 3, 5, 7, 8, 6, 4, 2};

The half side in the front array are odd numbers, and the rest (the equal amount number) are even. 前阵列中的半边是奇数,其余(等量数)是偶数。 The odd numbers are in an ascending order and even part are in a descending order. 奇数按升序排列,偶数部分按降序排列。 After the sorting, the order of the numbers can't be changed. 排序后,数字的顺序不能改变。

How can I sort them alternatively with time complexity less than O(n^2) and space complexity O(1) ? 如何以时间复杂度小于 O(n^2)和空间复杂度O(1)对它们进行排序?

For this example, the result would be: {1,8,3,6,5,4,7,2} ; 对于这个例子,结果将是: {1,8,3,6,5,4,7,2} ;

I can't use external array storage but temporary variables are acceptable. 我不能使用外部数组存储,但临时变量是可以接受的。

I have tried to use two pointers( oddPtr, evenPtr ) to point odd and even numbers separately, and move evenPtr to insert the even values to the middles of odd numbers.(Like insertion sort) 我试图使用两个指针( oddPtr, evenPtr )分别指向奇数和偶数,并移动evenPtr以将偶数值插入奇数的中间。(如插入排序)
But it takes O(n^2) . 但它需要O(n^2)

UPDATED 更新

As per Dukeling's comment I realized that the solution I propose in fact is not linear,but linearithmic and even worse - you can't control if it takes extra memory or not. 根据Dukeling的评论,我意识到我提出的解决方案实际上不是线性的,而是线性的,甚至更糟 - 你无法控制它是否需要额外的内存。 On my second thought I realized you know a lot about the array you to implement a more specific, but probably easier solution. 在我的第二个想法中,我意识到你对阵列有很多了解,你可以实现更具体,但可能更简单的解决方案。

I will make an assumption that all values in the array are positive. 我将假设数组中的所有值都是正数。 I need this so that I can use negative values as kind of 'already processed' flag. 我需要这个,以便我可以使用负值作为“已处理”标志。 My idea is the following - iterate over the array from left to right. 我的想法如下 - 从左到右遍历数组。 For each element if it is already processed(ie its value is negative) simply continue with the next one. 对于每个元素,如果它已经被处理(即它的值为负),只需继续下一个元素。 Otherwise you will have a constant formula where is the position where this element should be: 否则你将有一个常量公式,其中该元素的位置应该是:

  • If the value is odd and its index is i it should move to i*2 如果该值为奇数且其索引为i ,则应移至i*2
  • If the value is even and its index is i it should move to (i - n/2)*2 + 1 如果值是偶数且其索引为i ,则应移至(i - n/2)*2 + 1

Store this value into a temporary and make the value at the current index of the array 0. Now until the position where the value we 'have at hand' is not zero, swap it with the value staying at the position we should place it according to the formula above. 将此值存储到临时值中并将值设置为数组0的当前索引。现在直到我们手头的值不为零的位置,将其与保留在我们应该放置的位置的值交换到上面的公式。 Also when you place the value at hand negate it to 'mark it as processed'. 此外,当您将值放在手边时,将其标记为“将其标记为已处理”。 Now we have a new value 'at hand' and again we calculate where it should go according to the formula above. 现在我们有一个新的价值'手头',我们再次根据上面的公式计算它应该去哪里。 We continue moving values until the value we 'have at hand' should go to the position with 0. With a little thought you can prove that you will never have a negative('processed') value at hand and that eventually you will end up at the empty spot of the array. 我们继续移动值,直到我们手边的值应该移到0的位置。稍微想一想你可以证明你手头上永远不会有负面('处理')价值,最终你会最终在阵列的空位。

After you process all the values iterate once over the array to negate all values and you will have the array you need. 处理完所有值后,在数组上迭代一次以取消所有值,您将获得所需的数组。 The complexity of the algorithm I describe is linear- each value will be no more than once 'at hand' and you will iterate over it no more than once. 我描述的算法的复杂性是线性的 - 每个值不会超过一次“手头”,你将迭代它不超过一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM