题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
这道题目的思路和快速排序很相似,不同点在于交换时不用考虑奇数/偶数序列内部的大小关系。快速排序时设置了两个指针,一个初始化指向最左端,一个初始化指向最右端,这道题目也是一样的操作。在左指针指向的内容小于右指针指向内容的前提下,循环检测左端是否有偶数和右端是否有奇数,若有,则交换两个指针所指的内容。
#include<stdio.h>
void Reorder2(int* a, int len) {
if ((a == NULL) || (*a == NULL) || (len == 0))
return;
int left = 0;
int right = len - 1;
while (left < right)
{
while ((left < right) && (a[left] & 1) != 0)
left++;
while ((left < right) && (a[right] & 1) == 0)
right--;
if (left < right) {
int temp = a[left];
a[left] = a[right];
a[right] = temp;
}
}
}
void test2() {
int a[] = { 3,4,9,6,2,5,9 };
int len = sizeof(a) / sizeof(int);
Reorder2(&a, len);
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
void main() {
test2();
}
上述函数就是按照这个思路编写的代码,可以看到可快速排序的结构很相似,只是快速排序在大循环结束后还要对指针左右两端分别排序。
如果不考虑代码的可重用性,这道题目到这里就结束了,但是快速排序和本题的逻辑框架是一样的,只是具体实现的功能不同。因此我们可以对代码进行重构,将逻辑和功能分到两个函数当中,针对不同的功能,只要修改功能函数即可。
要实现逻辑与功能分离,需要用到函数指针。
函数指针
函数指针的概念:如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。
定义:函数的返回值类型 (*指针变量名)(函数参数的类型列表);
令函数指针指向函数的首地址:指针变量名 = 函数名称;
调用:返回值 = (*指针变量名)(函数的具体参数);
在本题中,上述三种函数指针的基本操作可表示为:
定义:int (*p)(int);
令函数指针指向函数的首地址:p = ReorderEvenOdd;
调用:返回值 = (*p)(a[具体下标]);
注意:
- 函数指针的定义中并不需要指明函数的名称,只需令其返回值类型与参数列表对应即可。
- 令函数指针指向函数的首地址时,不带括号、也不带参数。
#include<stdio.h>
#define true 1
#define false 0
void Reorder(int* a, int len, int (*p)(int)) {
if ((a == NULL) || (*a == NULL) || (len == 0))
return;
int left = 0;
int right = len - 1;
while (left < right)
{
while ((left < right) && (*p)(a[left]))
left++;
while ((left < right) && !(*p)(a[right]))
right--;
if (left < right) {
int temp = a[left];
a[left] = a[right];
a[right] = temp;
}
}
}
int ReorderEvenOdd(int x) {
if ((x & 1) != 0)
return true;
else
return false;
}
void test1() {
int a[] = { 3,4,9,6,2,5,9 };
int len = sizeof(a) / sizeof(int);
int(*p)(int);
p = ReorderEvenOdd;
Reorder(&a, len, p);
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
void main() {
test1();
}
扫描二维码关注公众号,回复:
9463552 查看本文章