《剑指offer》 -- (8)调整数组顺序使奇数位于偶数前面

题目描述:

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使的所有奇数位于数组的前半部分,所有的偶数位于数组的后半部分。

思路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是一个具体的标准。

猜你喜欢

转载自blog.csdn.net/zhuoya_/article/details/80638534