标签:
题目:输入一个整数数组,实现一个函数来解决该数组中数字的位置,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
本题思路较为简单,我们只需维护两个指针:第一个指针pHead 初始化为数组的第一个元素,第二个指针pTail 初始化为数组的最后一个元素。根据题目要求:所有奇数位于数组的前半部分,偶数位于数组的后半部分;我们只需:
1、使指针pHead 向后遍历,直到指向的整数为偶数;
2、使指针pTail 向前遍历,直到指向的整数为奇数;
3、交换指针pHead 和指针pTail 所指向的元素。
4、在 pHead 和 pTail 相遇之前,pHead继续向后遍历,pTail继续向前遍历。
实现代码为:
1 #include "stdio.h" 2 #include "stdlib.h" 3 4 #define N 10 5 6 void swap(int *left, int *right); 7 void printArr(int *arr, int len); 8 void initArr(int *arr, int len); 9 void reorderOddEven(int *arr, int len); 10 11 void swap(int *left, int *right) 12 { 13 int tmp = *left; 14 *left = *right; 15 *right = tmp; 16 } 17 18 void printArr(int *arr, int len) 19 { 20 int i; 21 for(i = 0; i < len; ++i) 22 { 23 printf("%3d", arr[i]); 24 } 25 printf("\n"); 26 } 27 28 void initArr(int *arr, int len) 29 { 30 int i; 31 for(i = 0; i < len; ++i) 32 { 33 arr[i] = rand() %100; 34 } 35 } 36 37 void reorderOddEven(int *arr, int len) 38 { 39 int *pHead = arr; 40 int *pTail = arr + len -1; 41 42 while(pHead < pTail) 43 { 44 while(pHead < pTail && (*pHead & 0x1) != 0) 45 pHead++; 46 47 while(pHead < pTail && (*pTail & 0x1) == 0) 48 pTail--; 49 50 if(pHead < pTail) 51 swap(pHead, pTail); 52 } 53 } 54 55 int main(int argc, char const *argv[]) 56 { 57 int arr[N] = {0}; 58 initArr(arr, N); 59 printf("Before: "); 60 printArr(arr, N); 61 62 reorderOddEven(arr, N); 63 printf("After: "); 64 printArr(arr, N); 65 66 return 0; 67 }
引入函数指针:
试考虑把题目改成如下情形: 1、把数组中的数按照大小分为两部分,所有负数都在非负数的前面,该怎么做? 2、把数组中的数分成两部分,能被 3 整除的数都在不能被 3 整除的数的前面。该怎么办?
实际上,上面两个问题是我们在开端那个题目的变形,只需改变 while 循环里的条件即可。因此我们可以把这个条件的逻辑框架抽象出来,而把判断的标准变成一个函数指针,也就是用一个单独的函数来判断数字是不是符合条件。因此上面的条件可以变成两个函数来解决:
1 bool isNegative(int n); 2 bool is3Multi(int n);
而上面的问题:把所有奇数排在偶数前面的问题,我们就可以用下面函数解决:
bool isEven(int n) { return (n & 0x1) == 0; }
完整的代码如下:
1 // reorderOddEven.cpp 2 #include "stdio.h" 3 #include "stdlib.h" 4 5 #define N 10 6 7 void reorderOddEven(int *arr, int len); 8 void Reorder(int *pData, unsigned int length, bool (*func)(int)); 9 bool isEven(int n); 10 11 void swap(int *left, int *right) 12 { 13 int tmp = *left; 14 *left = *right; 15 *right = tmp; 16 } 17 18 void printArr(int *arr, int len) 19 { 20 int i; 21 for(i = 0; i < len; ++i) 22 { 23 printf("%3d", arr[i]); 24 } 25 printf("\n"); 26 } 27 28 void initArr(int *arr, int len) 29 { 30 int i; 31 for(i = 0; i < len; ++i) 32 { 33 arr[i] = rand() % 100; 34 } 35 } 36 37 void reorderOddEven(int *arr, int len) 38 { 39 if(!arr || len <= 0) 40 return; 41 42 Reorder(arr, len, isEven); 43 } 44 45 void Reorder(int *pData, unsigned int length, bool (*func)(int)) 46 { 47 int *pBegin = pData; 48 int *pEnd = pData + length - 1; 49 50 while(pBegin < pEnd) 51 { 52 // 向后移动pBegin 53 while(pBegin < pEnd && !func(*pBegin)) 54 pBegin ++; 55 56 // 向前移动pEnd 57 while(pBegin < pEnd && func(*pEnd)) 58 pEnd --; 59 60 if(pBegin < pEnd) 61 swap(pBegin, pEnd); 62 } 63 } 64 65 bool isEven(int n) 66 { 67 return (n & 0x1) == 0; 68 } 69 70 int main(int argc, char const *argv[]) 71 { 72 int arr[N] = {0}; 73 initArr(arr, N); 74 printf("Before: "); 75 printArr(arr, N); 76 77 reorderOddEven(arr, N); 78 printf("After: "); 79 printArr(arr, N); 80 81 return 0; 82 }
本文完。
【剑指offer】面试题14、调整数组顺序使奇数位于偶数前面
标签:
原文地址:http://www.cnblogs.com/xfxu/p/4586052.html