奇偶数排序(调序)

题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,

所有偶数位于数组的后半部分。要求时间复杂度为O(n)。

思路一:从头扫描这个数组,每碰到一个偶数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位。由于碰到一个偶数,需要移动O(n)个数字,只是这种方法总的时间复杂度是O(n),不符合要求!

思路二:采用依次遍历数组的方式,从数组的第一个元素开始,判断元素是否是奇数,如果是则将它保存到另一个空数组中,当遍历完整个数组中的奇数时,就将原数组中的所有偶数按照原顺序依次保存到数组的末尾。空间复杂度太大,时间复杂度也不满足要求。

思路三:维护两个指针(头指针和尾指针),一个指针指向数组的第一个数字(头指针),向后移动;一个指针指向最后一个数字(尾指针),向前移动。如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字。(类似于快速排序)

本方法通过头尾指针往中间扫描,一次遍历完成所有的奇数和偶数的重新排列,时间复杂度是O(n),符合题目要求。(使用)

思路四:还记得快速排序的过程,设置一个主元,依次遍历元素并使得它和主元进行比较,并按照要去交换元素的位置。

该问题使用两个指针i和j,一个指针指向数组的第一个元素的前一个位置,称为后指针i,向右移动;另一个指针指向数组的第一个元素,称为前指针j,向右移动。前后指针都向后移动的过程中,如果前指针j指向的元素是奇数,则令后指针i向右移动一位,然后交换i和j两个指针所各自指向的元素。我们最终的目的是让奇数排在数组的前面,偶数排在数组的后面,所以i指针指向的是奇数,j指针指向的是偶数。因此,当j指针指向的是奇数时,不正常,让i++,然后交换i,j指针所指向的数。

这种一前一后同时向右扫描的解法,也是一次遍历奇数和偶数的重新排列,时间复杂度是O(n),符合题目要求。(使用)

总结:虽然思路三和四都实现了,但是它们的输出却有点差别。

//奇偶数排序

//思路三
#include <iostream>

using namespace std;

//判断是否为奇数
bool IsOddNumber(int data)
{
	if (data % 2 == 1)//
		return true;
	else
		return false;
	//return (data & 1) == 1;
}

//奇数和偶数的互换
void OddEvenSort(int *pData, unsigned int length)
{
	if (pData == NULL || length == 0)
	{
		return;
	}
	int *first = pData;
	int *second = pData + length - 1;

	while (first < second)
	{
		//如果头指针指向奇数,正常
		if (IsOddNumber(*first) == 1)
		{
			first++;
		}
		else if (IsOddNumber(*second) == 0) // 如果尾指针指向偶数,正常
		{
			second--;
		}
		else//如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字
		{
			int temp = *second;
			*second = *first;
			*first = temp;
		}
		
	}

}

int main()
{
	int a[8] = { 1, 6, 3, 10, 4, 7, 2, 5 };
	OddEvenSort(a, 8);
	
	for (int i = 0; i < 8; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;

	return 0;
}
//输出:1 5 3 7 4 10 2 6


//思路四
#include <iostream>

using namespace std;

//判断是否为奇数
bool IsOddNumber(int data)
{
	if (data % 2 == 1)//奇数
		return true;
	else
		return false;
	//return (data & 1) == 1;
}

//奇数和偶数互换
void CddEvenSort2(int data[], int low, int high)
{
	int i = low - 1;
	for (int j = low; j < high; j++)
	{
		if (IsOddNumber(data[j]) == 1)//偶数
		{
			i++;
			swap(data[i], data[j]);
		}
	}
	swap(data[i + 1], data[high]);
}
int main()
{
	int a[8] = { 1, 6, 3, 10, 4, 7, 2, 5 };
	CddEvenSort2(a, 0, 7);
	
	for (int i = 0; i < 8; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;

	return 0;
}
//输出:1 3 7 5 4 6 2 10



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值