面试题21:调整数组顺序使奇数位于偶数前面
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
方法一:利用两个指针(只完成基本功能的解法, 仅适用于初级程序员)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
/**
* 只完成基本功能的解法, 仅适用于初级程序员
* 利用两个指针对数字进行交换
**/
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;
}
}
}
int main() {
int arr[]={1, 2, 3, 4, 5};
ReorderOddEven(arr, 5);
for(int i=0;i<5;i++){
printf("%d", arr[i]);
}
return 0;
}
方法二:把判断逻辑抽象出来,能解决同类问题(考虑可扩展的解法,能秒杀Offer)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
/**
* 考虑可扩展的解法,能秒杀Offer
* 抽象出判断逻辑,对同类型问题给出通用办法
* 类型问题:所有负数弄到非负数的前面、能被3整除的数都在不能被3整除的数的前面等等
**/
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){
// 向后移动 pBegin, 通过func判断
while(pBegin<pEnd && !func(*pBegin)) pBegin++;
// 向后移动 pBegin, 通过func判断
while(pBegin<pEnd && func(*pEnd)) pEnd--;
if(pBegin<pEnd){
int temp=*pBegin;
*pBegin=*pEnd;
*pEnd=temp;
}
}
}
bool isEven(int n){
return (n&1)==0;
}
void ReorderOddEven(int* pData, unsigned int length){
Reorder(pData, length, isEven);
}
int main() {
int arr[]={1, 2, 3, 4, 5};
ReorderOddEven(arr, 5);
for(int i=0;i<5;i++){
printf("%d", arr[i]);
}
return 0;
}