剑指offer面试题14 :输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使奇数都位于偶数前面。第一想法是,new一个新数组,然后遍历原来的数组,遇到奇数从前往后存到新数组里,遇到偶数从后往前存到新数组里,这种想法肯定浪费空间,而且不一定允许。阅读过思路后自己动手实现代码:
代码如下:
void ReorderOddEven(int* number,int length)
{
//int length = strlen(number);
if ( number == NULL || length == 0)
{
return ;
} //这一段其实是后来看过书加的
int p1 = 0;
int p2 = length -1;
while(p1 < p2)
{
while ( number[p1] % 2)
{
p1 ++;
}
while( number[p2] %2 == 0)
{
p2 --;
}
if (p1 < p2)
{
SwapNumber(number[p1] ,number[p2]);
}
}
}
SwapNumber是一个交换函数,代码如下:
void SwapNumber(int &x,int &y)
{
int temp = 0;
temp = x;
x= y;
y = temp;
}
test函数:
void coutArray( int* array,unsigned int length)
{
for( int i =0;i < length ;i++)
{
cout<<array[i]<<endl;
}
}
void test()
{
int number[5] = {2,4,6,1,9};
ReorderOddEven(number,5);
coutArray(number,5);
}
void test2()
{
<span style="white-space:pre"> </span> int * number = NULL;
<span style="white-space:pre"> </span> ReorderOddEven(number,0);
<span style="white-space:pre"> </span> coutArray(number,0);
}
main函数:
int main()
{
test();
test2();
system("pause()");
return 0;
}
书上给出的例子程序:
void ReorderOddEven_1(int *pData, unsigned int length)
{
if(pData == NULL || length == 0)
return;
int *pBegin = pData;
int *pEnd = pData + length - 1;
while(pBegin < pEnd)
{
// 向后移动pBegin,直到它指向偶数
while(pBegin < pEnd && (*pBegin & 0x1) != 0)
pBegin ++;
// 向前移动pEnd,直到它指向奇数
while(pBegin < pEnd && (*pEnd & 0x1) == 0)
pEnd --;
if(pBegin < pEnd)
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}
测试案例自己的代码也基本都能通过,但是和源码比较,主要不同在于以下三点:
1 ,没有考虑空数组,虽然程序安全返回,但是明显显出不专业,代码没有容错性能。
2 ,对于偶数奇数的判断,自己使用取余% 判断,源码使用 & 0x1 与1‘与’的方式判断,很明显,与是按位操作,肯定比除法求余速率高的多,不经常使用 位操作,这个细节可以反映出功底。
3,至于数组元素的访问,自己使用下标,源码是使用指针访问,通过下标和指针访问的速率问题,参考这里,自己是觉得,使用下标可能更安全一些吧。
后来书中提出的可扩展性解法,源码不难,重要的是思想,想要源码的可以私信我。