您的位置:首页 > 编程语言 > C语言/C++

【C++】调整数组顺序使奇数位于偶数前面

2015-09-11 15:40 447 查看
最简单的做法是,从头扫描数组,碰到一个偶数则把这个偶数拿出来,然后将这个偶数后面的数字都往前移动一位,移动完毕后在数组末尾有一个空位,这时把该偶数放入这个空位。这样做的时间复杂度是O(n2)。

时间复杂度更低的办法有吗?有的。

维护两个指针,一个位于数组开头,只往后移动,一个位于数组末尾,只往前移动。并且第一个指针总是位于第二个指针前面。如果第一个指针指向偶数,并且第二个指针指向奇数,就交换这两个指针指向的数字。

<span style="font-family:Microsoft YaHei;">void RecordOddEven(int *pData, unsigned int length)
{
if(pData == NULL || length == 0) return;
int *pBegin = pData;
int *pEnd = pData + length -1;
while(pBegin < pEnd)
{
//step over pBegin until it points to an even value
while (pBegin < pEnd && !isEven(*pBegin) )
{
pBegin++;
}
//step over pEnd until it points to an odd value
while (pBegin < pEnd && isEven(*pEnd) )
{
pEnd--;
}
if(pBegin < pEnd)
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}</span>


那么如果题目是把数组中的数字按照大小分成两部分,所有负数都在非负数前面,或者把所有数字分成两部分,所有能被3整除的都在不能被3整除的前面呢?

这和上面的问题其实是同一类问题,只需要把第二个和第三个while循环中的条件判断改一下就可以了。那么可以把这部分提取出来模块化,用一个单独的函数判断是否符合标准。

<span style="font-family:Microsoft YaHei;">void RecordOddEven(int *pData, unsigned int length)
{
if(pData == NULL || length == 0) return;
int *pBegin = pData;
int *pEnd = pData + length -1;
while(pBegin < pEnd)
{
//step over pBegin until it points to an even value
while (pBegin < pEnd && !isEven(*pBegin) )
{
pBegin++;
}
//step over pEnd until it points to an odd value
while (pBegin < pEnd && isEven(*pEnd) )
{
pEnd--;
}
if(pBegin < pEnd)
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}

bool isEven(int n)
{
return (n & 0x1) == 0;
}</span>


单元测试应该包括:

1. 奇数偶数交替出现

2. 所有偶数都在奇数前面

3. 所有偶数都在奇数后面

4.特殊输入: NULL指针, 只包含一个数字
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: