调整数组顺序实现:奇数在偶数前面 以及 “奇偶奇偶”相间

题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)

利用快排的两种实现方法,一种是前后两个指针向中间移动,另外一种是算法导论上快排的划分方法,也是两个指针,但都从头开始。

算法一,前后两个指针

#include <iostream>
#include <algorithm>
using namespace std;

bool isEven(int n)
{
	return (n & 1)==0;
}

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(!func(*pBegin))
			pBegin++;
		
		while(func(*pEnd))
			pEnd--;
		
		swap(*pBegin, *pEnd);
		pBegin++;
		pEnd--;
		
	}
	
}

void main()
{
	int a[]={1,3,6,4,9,10,13};
	Reorder(a, 7, isEven);
	for(int i=0; i<7; i++)
		cout<<a[i]<<" ";
	cout<<endl;
}


算法二,参见算法导论快速排序的数组划分

#include <iostream>
#include <algorithm>
using namespace std;

bool isEven(int n)
{
	return (n & 1)==0;
}

void Partition(int *pData, unsigned int length, bool (*func)(int))//算法导论上快排的划分思想,实现奇数在前,偶数在后
{
	int i=-1;
	for(int j=0; j<length; j++)
	{
		if(!func(*(pData+j)))
		{
			i++;
			swap(*(pData+i), *(pData+j));
			
		}
	}
}

void main()
{
	int a[]={1,3,6,4,9,10,13};
	Partition(a, 7,isEven);
	for(int i=0; i<7; i++)
		cout<<a[i]<<" ";
	cout<<endl;
}

 

变形:处理数组实现“奇偶奇偶”相间的格式

利用算法导论快排的数组划分思想,让i(确切的说是i+1)指向需要交换的位置,j从i后一个位置开始遍历,找到第一个符合要求的数与i位置的数进行交换。

#include <iostream>
#include <algorithm>
using namespace std;

bool isEven(int n)
{
	return (n & 1)==0;
}

void OddandEven(int *pData, unsigned int length, bool (*func)(int))//参考算法导论上快排的划分思想,实现数组的“奇偶奇偶”相间
{
	int i=-1;
	bool flag=true;
	int j=0;
	while(j<length)
	{
		if( func(j)!=func(*(pData+j)) )
		{
			if(flag)
				i++;
			
		}
		else
		{
			flag=false;
			if(func(i+1)!=func(j))
			{
				i++;
				swap(*(pData+i), *(pData+j));
				flag=true;
				j=i;
			}
		}
		j++;		
	}
}

void main()
{
	int a[]={1,3,6,4,9,10,13};
	//	Reorder(a, 7, isEven);
	//	Partition(a, 7,isEven);
	OddandEven(a, 7, isEven);
	for(int i=0; i<7; i++)
		cout<<a[i]<<" ";
	cout<<endl;
}




 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值