这道题题目可以描述为:输入一个整数数组,实现一个函数来调整数组中数字的顺序。使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
本题思路基本可以概括为:维护两个指针begin和end,第一个指针begin初始化时指向数组的第一个数字,它只向后移动;第二个指针end初始化时指向数组的最后一个数字,它只向前移动。在两个指针相遇前,begin总是位于end的前面。如果begin指向偶数,end指向奇数,这时就交换他们即可。如下图所示
代码如下:
#include<stdio.h>
#include<stdlib.h>
void ReorderOddEvn(int *p, int length)
{
if (p == NULL&&length == 0)
{
return;
}
int *begin = p;
int *end = p + length - 1;
while (begin < end)
{
//如果begin指向奇数
while (begin < end&&*begin % 2 == 1)
{
begin++;
}
//如果end指向偶数
while (begin < end&&*end % 2 == 0)
{
end--;
}
if (begin < end)
{
int temp = *begin;
*begin = *end;
*end = temp;
}
}
}
int main()
{
int arr1[8] = { 2, 4, 6, 8, 1, 3, 5, 7 };
ReorderOddEvn(arr1, 8);
for (int i = 0; i < 8; i++)
{
printf("%d ", arr1[i]);
}
system("pause");
return 0;
}
其实,对这道题还可以考虑可扩展性的解法,例如把数组中元素按大小分为两部分,所有负数排在正数前面,这个例子与本题基本是同一类型。其实我们应该考虑总结出一个模式,在这个模式下能很方便的把已有问题的解决方案扩展到同类型问题上去。
这种通用方法可以总结为可以把判断的标准独立封装成一个函数,用来判断数字是不是符合标准。这样可以把整个函数分为两部分:一是判断数字在前半部分还是后半部分的标准,二是拆分数组的操作。代码如下:
#include<stdio.h>
#include<stdlib.h>
int IsEven(int n)
{
return(n % 2) == 1;
}
void ReorderOddEvn(int *p, int length)
{
if (p == NULL&&length == 0)
{
return;
}
int *begin = p;
int *end = p + length - 1;
while (begin < end)
{
//如果begin指向奇数
while (begin < end&&!IsEven(*begin))
{
begin++;
}
//如果end指向偶数
while (begin < end&&IsEven(*end))
{
end--;
}
if (begin < end)
{
int temp = *begin;
*begin = *end;
*end = temp;
}
}
}
int main()
{
int arr1[8] = { 2, 4, 6, 8, 1, 3, 5, 7 };
ReorderOddEvn(arr1, 8);
for (int i = 0; i < 8; i++)
{
printf("%d ", arr1[i]);
}
system("pause");
return 0;
}