我已经实现了一个算法来更改数组,以便将所有偶数移动到数组的开头,将旧数字移动到数组的末尾。这是我的计划: -
#include <iostream>
using namespace std;
void print(int arr[], int size) {
for(int i=0;i<size;i++) {
cout<<arr[i]<<" ";
}
cout<<endl;
}
void segregate(int arr[], int size) {
int l=0, h=size-1;
while(l<h) {
while(!(arr[l]%2) && l<size) {
l++;
}
while((arr[h]%2) && h >=0) {
h--;
}
swap(arr[l], arr[h]);
}
}
int main() {
int arr[] = {1,2,3,4,5,6,7,8,9};
int size = 9;
print(arr,size);
segregate(arr,size);
print(arr,size);
return 0;
}
我没有得到预期的结果
1 2 3 4 5 6 7 8 9
8 2 6 5 4 3 7 1 9
我错过了什么?
答案 0 :(得分:5)
您要做的事情也称为分区。标准库提供了两种算法:std::partition
和std::stable_partition
。
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9};
auto split = std::partition( std::begin(arr), std::end( arr ),
[]( int a ) { return ! a%2; } );
// [ begin, split ) are all even
// [ split, end ) are all odd
}
如果您对writing your own仍感兴趣,cppreference对std::partition
的描述包含等效代码。
您的版本在交换之前缺少if
语句。你应该只在左边有一个奇数时交换。
答案 1 :(得分:2)
问题1:
只有当swap
未越过l
时,您才需要致电h
,而您总是在呼叫它。
考虑已经分类的数组{2,1}
现在,在两个内部while循环l
将1
和h
将0
之后。在你的情况下,你将继续交换,但是因为l
越过h
,所以不需要交换。
当发生这种情况时,阵列已经被隔离了。
所以改变
swap(arr[l], arr[h]);
到
if(l<h) {
swap(arr[l], arr[h]);
}
问题2:
还必须颠倒内部while循环中的条件顺序。你正在检查
while(number at index l is even AND l is a valid index) {
l++;
}
这是不正确的。考虑一个数组{2,4}
,现在在上面的某个时刻,while循环l
将是2
,然后你继续访问arr[2]
,这是不存在的。
您需要的是:
while(l is a valid index AND number at index l is even) {
l++;
}
答案 2 :(得分:2)
尽可能简单:
void partitionEvenOdd(int array[], int arrayLength, int &firstOdd)
{
firstOdd = 0;
for (int i = 0; i < arrayLength; i++) {
if (array[i]%2 == 0) {
swap(array[firstOdd], array[i]);
firstOdd++;
}
}
}
答案 3 :(得分:1)
你不能只使用标准排序吗?
类似的东西:
#include <stdio.h>
#include <stdlib.h>
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b)
{
// return -1 a-even and b-odd
// 0 both even or both odd
// 1 b-even and a-odd
}
qsort (values, 6, sizeof(int), compare);