您的位置:首页 > 职场人生

剑指offer_面试题14_调整数组顺序使奇数位于偶数前面(函数指针用法)

2015-08-09 21:06 686 查看
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

1、一般想法,不考虑时间复杂度:

每次遍历数组,碰到一个偶数就拿出来,将后面所有数字向前挪动一位,在将该偶数放到最后。

2、利用冒泡排序的思想,两个指针,一前以后,如果前为偶数,后为奇数,就交换。

算法如下:

void Reorder_array(int p[],int length)
{
if(NULL == p || length <= 0)
return;

int i,j;
int temp;
for(i = 0; i < length; i++)
{
for(j = length - 1; j > i; j--)
{
if(p[i]%2 == 0 && p[j]%2 != 0)  /**头指向偶数,尾指向奇数,交换两者*/
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
if(p[i]%2 != 0)   /**头指针指向奇数,跳出内循环,i++*/
{
break;
}
/**尾指针指向偶数,就什么不干,等待j--*/
}
}
for(i = 0; i < length; i++){
cout << p[i] << ' ';
}
cout << endl;
}
下面是书上的写法,感觉比我写的好:

逻辑比较清晰,并且用 位与运算,代替了 取余运算,提高了运算效率。

void Reorder_array_from_book(int *pData, unsigned int length)
{
if(pData == NULL || length == 0)
return;
int *pBegin = pData;
int *pEnd = pData + length - 1;
while(pBegin < pEnd)
{
while(pBegin < pEnd && (*pBegin & 0x1) != 0)    /**取余运算用 & 代替了*/
pBegin++;
while(pBegin < pEnd && (*pEnd & 0x1) == 0)
pEnd--;
if(pBegin < pEnd)
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}
考虑 位与 运算,并且考虑 算法的扩展性,使用了函数指针。

/**函数指针写法,可提高扩展性,需要重视*/
bool isEven(int pData)
{
return (pData & 0x1) == 0;
}

void Reorder_array_pre(int p[],int length,bool (*func)(int))
{
if(NULL == p || length <= 0)
return;

int i,j;
int temp;
for(i = 0; i < length; i++)
{
for(j = length - 1; j > i; j--)
{
if(func(p[i]%2) && !func(p[j]%2))  /**头指向偶数,尾指向奇数,交换两者*/
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
if(!func(p[j]%2))   /**头指针指向奇数,跳出内循环,i++*/
{
break;
}
/**尾指针指向偶数,就什么不干,等待j--*/
}
}

for(i = 0; i < length; i++){
cout << p[i] << ' ';
}
cout << endl;

}
测试代码:

int main()
{
//int p[11] = {1,2,3,4,5,9,3,11,66,55,68};
int p[10] = {0,1,2,3,4,5,6,7,8,9};
//int p[8] = {2,2,2,2,1,1,1,1};
//int p[1] = {1};
//Reorder_array(p,8);
Reorder_array_pre(p,10,isEven);    /**这里传递的是指针,所以是改变了原数组的内容*/
/*
for(int i = 0; i < 10; i++){
cout << p[i] << ' ';
}
cout << endl;
*/
return 0;
}


结果:



/*点滴积累,我的一小步O(∩_∩)O~*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: