更多题目:《 剑指offer》 目录索引
题目描述:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
方法一:
利用左右指针,left和right。left指向数组首元素,right指向数组尾元素。
左指针从左往右找,找到偶数停止
- 右指针从右往左找,找到奇数停止
- 交换左右指针的元素
- 当左右指针分别指向数组中的最后一个奇数和偶数时,数组调整完毕
代码:
void Reorder(int *pData, unsigned int length)
{
if (pData == NULL || length < 0)
return;
int* start = pData;//第一个
int* finish = pData +length - 1;//最后一个
while (start < finish)
{
while (start < finish && ((*start & 1) != 0))//找到偶数就停止
{
start++;
}
while (start < finish && ((*finish & 1) == 0))//找到奇数就停
{
finish--;
}
if (start < finish)
{
int tmp = *start;
*start = *finish;
*finish = tmp;
}
}
}
方法二:
上述方法中,利用左右指针找到奇数和偶数,并且采用&操作符进行判断,但这有一个缺陷,只能解决奇数和偶数的问题,但此题还有很多扩展题目,例如:负数和非负数,素数和合数。。。。。。此时,我们需要将其判断条件封装成一个函数,以后改变判断条件即可,就可解决不同的扩展题目
代码:
//偶数返回0,奇数返回1
bool isEven(int n)
{
return (n&1)== 0;
}
void Reorder1(int *pData, unsigned int length, bool(*func)(int))
{
if (pData == NULL || length < 0)
return;
int* start = pData;//第一个
int* finish = pData + length - 1;//最后一个
while (start < finish)
{
while (start < finish && !func(*start))//找到偶数就停止
{
start++;
}
while (start < finish && func(*finish))//找到奇数就停
{
finish--;
}
if (start < finish)
{
int tmp = *start;
*start = *finish;
*finish = tmp;
}
}
}
测试用例:
// ====================测试代码====================
void PrintArray(int numbers[], int length)
{
if (length < 0)
return;
for (int i = 0; i < length; ++i)
printf("%d\t", numbers[i]);
printf("\n");
}
void Test(char* testName, int numbers[], int length)
{
if (testName != nullptr)
printf("%s begins:\n", testName);
int* copy = new int[length];
for (int i = 0; i < length; ++i)
{
copy[i] = numbers[i];
}
printf("Test for solution 1:\n");
PrintArray(numbers, length);
Reorder1(numbers, length, isEven);
PrintArray(numbers, length);
printf("\n\n");
printf("Test for solution 2:\n");
PrintArray(copy, length);
Reorder1(copy, length, isEven);
PrintArray(copy, length);
printf("\n************************************************************\n");
delete[] copy;
}
//正常
void Test1()
{
int numbers[] = { 1, 2, 3, 4, 5, 6, 7 };
Test("Test1", numbers, sizeof(numbers) / sizeof(int));
}
//偶数在前,奇数在后
void Test2()
{
int numbers[] = { 2, 4, 6, 1, 3, 5, 7 };
Test("Test2", numbers, sizeof(numbers) / sizeof(int));
}
//奇数在前,偶数在后
void Test3()
{
int numbers[] = { 1, 3, 5, 7, 2, 4, 6 };
Test("Test3", numbers, sizeof(numbers) / sizeof(int));
}
//只有一个数字,为奇数
void Test4()
{
int numbers[] = { 1 };
Test("Test4", numbers, sizeof(numbers) / sizeof(int));
}
//只有一个数字,为偶数
void Test5()
{
int numbers[] = { 2 };
Test("Test5", numbers, sizeof(numbers) / sizeof(int));
}
//数组不存在
void Test6()
{
Test("Test6", nullptr, 0);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
system("pause");
return 0;
}
结果: