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

面试算法(十三)调整数组顺序使奇数位于偶数前面

2014-07-12 22:25 323 查看
1、题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

解法:若不考虑时间复杂度,最简单的思路是从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个是数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于每碰到一个偶数就需要移动O(n)个数字,因此总的时间复杂度是O(n^2)。

方法:

扫描数组时,如果发现有偶数出现在奇数的前面,交换他们的顺序即可。我们维护两个指针,第一个指针初始化是指向数组的第一个数字,它只向后移动。第二个指针初始化时指向数组的最后一个数字,它只向前移动。在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数,并且第二个指针指向的数字是奇数,就交换这两个数字。

void ReorderOddEven(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;
		}
	}
}


2、题目扩展:

把题目改成把数组中的数按照大小分为两部分,所有负数都排在非负数的前面,怎么办?

解法:只需修改函数ReorderOddEven中的两处判断的标准即可。把判断的标准变成一个函数指针,也就是用一个单独的函数来判断数字是不是符合标准。这样就把函数分为两部分:一是判断数字应该在数组前半部分还是后半部分的标准,二是拆分数组的操作。

void Reorder(int *pData, unsigned int length, bool (*func)(int))
{
	if(pData == NULL || 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;
}


函数Reorder根据func的标准把数组pData分成两部分,函数isEven则是一个具体的标准,即判断一个数是不是偶数。

void ReorderOddEven(int *pData, unsigned int length)
{
	Reorder(pData, length, isEven);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐