题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使的所有奇数位于数组的前半部分,所有的偶数位于数组的后半部分。
思路1:将数组中的数字分为两部分,那我们可以在遍历数组的时候多定义一个变量,让该变量来存储奇数,在遍历的过程中如果遇到奇数,则交换。
很快可以写下如下代码:
void Move1(int *arr,int len,bool pfunc(int))//pfunc为函数指针
{
if(NULL==arr || len<=0)
return ;
int k=-1;
int i=0;
while(i<len)
{
if(!pfunc(arr[i]))//如果arr[i]为奇数,则增大k的范围
{
k++;
SWAP(arr[i],arr[k]);
}
i++;
}
}
bool fun(int n)
{
return (n&1)==0;
}
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,12};
int len=sizeof(arr)/sizeof(arr[0]);
Move1(arr,len,fun);
for(int i=0;i<len;i++)
cout<<arr[i]<<" ";
cout<<endl;
return 0;
}
2、当然也可以用两个前后指针来遍历数组:
void Move2(int *arr,int len,bool (*func)(int))//第一种:用两个指针
{
if(NULL==arr || len<=0)
return ;
int *begin=arr;//首指针
int *end=arr+len-1;//尾指针
while(begin<end)
{
while(begin<end && !func(*begin))//while(begin<end && (*begin & 0x1)!=0)
begin++;
while(begin<end && func(*end))//while(begin<end && (*begin & 0x1)==0)
end--;
if(begin<end)
SWAP(*begin,*end);
}
}
void Move3(int *arr,int len,bool (*func)(int))//第二种:用两个下标来代替指针
{
if(NULL==arr || len<=0)
return ;
int i=0;
int j=len;//j用来记录偶数的下标
while(i<j)
{
while(i<j && !func(arr[i]))
i++;
while(i<j && func(arr[j]))
j--;
if(i<j)
{
SWAP(arr[i],arr[j]);
i++;
j--;
}
}
}
bool fun(int n)
{
return (n&1)==0;
}
int main()
{
int brr[]={1,2,3,4,5,6,7,8,9,12};
Move2(brr,len,fun);
for(int i=0;i<len;i++)
{
cout<<brr[i]<<" ";
}
cout<<endl;
int crr[]={1,2,3,4,5,6,7,8,9,12};
Move3(crr,len,fun);
for(int i=0;i<len;i++)
{
cout<<crr[i]<<" ";
}
cout<<endl;
return 0;
}
说明:为什么要用函数指针呢?因为这样不仅可以解决一类题,而且在面临具体的问题时,我们只需要修改具体的fun函数就可以了,提高了代码的重用度。
在函数Move中,根据pfunc的标准把数组分为了两个部分,函数fun是一个具体的标准。