【劍指offer】面試題14、調整數組順序使奇數位於偶數前面


題目:輸入一個整數數組,實現一個函數來解決該數組中數字的位置,使得所有奇數位於數組的前半部分,所有偶數位於數組的后半部分。

本題思路較為簡單,我們只需維護兩個指針:第一個指針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 }
View Code

 

引入函數指針:

試考慮把題目改成如下情形:
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 }
View Code

 

本文完。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM