题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分。
思路1:
这道题可以联想到“Two Points”的经典解题思路,就是建立两个指针分别指向数组的首末元素,第一个指针指的元素如果是奇数就把指针往后滑动,直到遇到一个偶数后停下来;第二个指针所指的元素如果是偶数就把指针向前移动,直到遇到一个奇数后停下来。这时候判断第一个指针是否在第二个指针的前面,如果是那么交换两个指针所指元素的值,如果不是,那么说明数组的调整结束。这样遍历一轮数组就可以完成对数组的调整。
代码:
void ReorderOddEven(int *pData, unsigned int length)
{
if (pData == nullptr || length == 0)
return;
int *pBegin = pData;
int *pEnd = pData + length + -1;
while (pBegin<pEnd)
{
while (pBegin < pEnd && (*pBegin & 0x1) != 0)
{
//向后移动pEnd,直到它指向偶数
pBegin++;
}
while (pBegin<pEnd && (*pEnd & 0x1)==0)
{
//向前移动pEnd,直到它指向奇数
pEnd--;
}
if (pBegin < pEnd)
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}
思路2:
这道题还可以扩展一下,比如将所有的负数调整到前面,正数调整到后面,或者将能整除3的数放到前面,其余的数放到后面。其实,交换的方法是不变的,变的的判断的条件。那么,为了提高函数的可扩展性,我们可以将调整和条件判断分成两个函数,这样当题目的调整内容发生改变时,只需要改变条件判断函数里面的内容就好了。这种做法可以很大地提高函数的可扩展性,面试的时候会让面试官更加满意。里面判断奇数还是偶数的方法(a&0x1)要学着用啊。
注意:
这里面涉及到一个知识点,就是函数指针作为函数参数传递。函数A作为参数传递给函数B时,函数B声明如下:
int A(int a,int b);
B(arg_list,int (*pA)(int, int));
函数B调用如下:
B(...,A);
代码:
void Reorder(int* pData, unsigned int length, bool(*func)(int))
{
if (pData == nullptr || length == 0)
return;
int*pBegin = pData;
int*pEnd = pData + length - 1;
while (pBegin<pEnd)
{
while (pBegin < pEnd && !func(*pBegin))
pBegin++;
while (pBegin < pEnd && func(*pEnd))
pEnd--;
if (pBegin < pEnd)
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}
bool isEven(int n)
{
return(n & 1) == 0;
}
void ReorderOddEven(int* pData, unsigned int length)
{
Reorder(pData, length, isEven);
}
复习:
前面的思路比较简单,还是要好好注意这种扩展性怎么来实现,即函数指针作为另外一个函数的参数。
二刷代码:
void Reorder(int* pData, unsigned int length,bool (*func)(int))
{
if (pData == nullptr || length == 0)
return;
int* pStart = pData;
int* pEnd = pData + length - 1;
while (pStart>pEnd)
{
while (!func(*pStart)&& pStart<pEnd)
{
pStart++;
}
while (func(*pEnd) ==0&&pStart<pEnd)
{
pEnd++;
}
if (pStart < pEnd)
{
int temp = *pStart;
*pStart = *pEnd;
*pEnd = temp;
}
}
}
bool isEven(int n)
{
return (n & 1) == 0;
}
void ReorderOddEven(int *pData, unsigned int length)
{
Reorder(pData, length, isEven);
}