题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前面部分,偶数位于数组的后面部分。
思路:要求时间复杂度是Ο(n)。
1:从头开始扫描数组,确定数是奇数不动,偶数的话就移动数组最后。这样每个偶数都要进行移动,最坏的时间复杂度达到Ο(n^2)。
2:用两个指针,头指针指向数组开始,尾指针指向数组末尾。它们分别向中间移动,如果头尾指针不是奇数,尾指针不是偶数,则交换它们。
代码如下:
#include <stdio.h>
void swap(int *x, int *y)
{
int iTemp;
iTemp = *x;
*x = *y;
*y = iTemp;
}
//identify it is even or not
//Input : n - an integer
//Output: if it is an even ,return 1
// otherwise return 0
int IsEven(int n)
{
return (n & 1) == 0;
}
//divide the array into two parts, left parts are all odd, right parts are all even
//Input:pArr - an array of integers
// iLen - the length of the array
// func - a function
void Rearrange(int *pArr, unsigned int iLen, int (*func)(int))
{
if(!pArr || iLen == 0)
return;
int *pBegin = pArr;
int *pEnd = pArr + iLen - 1;
while(pBegin < pEnd){
if(!func(*pBegin)){//it's odd
pBegin++;
continue;
}
if(func(*pEnd)){//it's even
pEnd--;
continue;
}
swap(pBegin,pEnd);
}
}
void RearrangeArray(int *pArr, unsigned int iLen)
{
if(!pArr || iLen == 0)
return;
Rearrange(pArr, iLen, IsEven);
}
int main(void)
{
int a[] = {2,5,5,12,4,6,2,4,6,7,3,5};
RearrangeArray(a, 12);
for(int i = 0; i < 12; i++)
printf("%d\n", a[i]);
return 0;
}
Rearrange用函数指针判断一个数是不是符合给定的条件,而不是用代码直接判断。这样的好处是把调整顺序的算法和调整标准分开,达到解耦(decouple)的目的。当调整的标准改变时,Rearrange的代码不需要修改,只需要提供一个新的确定调整标准的函数即可,提高了代码的可维护性。
只扫描了一遍数组,时间复杂度是Ο(n)。
以下是写的比较差的代码:
//调整数组顺序使奇数位于偶数前面
#include <stdio.h>
void swap(int *x, int *y)
{
int iTemp;
iTemp = *x;
*x = *y;
*y = iTemp;
}
int RearrangeArray(int *pArr, int iStart, int iEnd)
{
if(!pArr)
return 0;
while(iStart < iEnd)
if((*(pArr + iStart) % 2 == 1 && *(pArr + iEnd) % 2 == 0) || (*(pArr + iStart) % 2 == 0 && *(pArr + iEnd) % 2 == 1) ){
swap(pArr + iStart, pArr + iEnd);
iStart++;
iEnd--;
}
else if(*(pArr + iStart) % 2 == 1 && *(pArr + iEnd) % 2 == 1)
iStart++;
else if(*(pArr + iStart) % 2 == 0 && *(pArr + iEnd) % 2 == 0)
iEnd--;
return 1;
}
int main(void)
{
int a[] = {1,2,3};
RearrangeArray(a, 0, 2);
for(int i = 0; i < 3; i++)
printf("%d\n", a[i]);
return 0;
}
参考: http://zhedahht.blog.163.com/blog/#m=0&t=1&c=fks_081075092084086069093074084070080087080066083082