題目:輸入一個整數數組,實現一個函數來解決該數組中數字的位置,使得所有奇數位於數組的前半部分,所有偶數位於數組的后半部分。
本題思路較為簡單,我們只需維護兩個指針:第一個指針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 }
本文完。