码迷,mamicode.com
首页 > 编程语言 > 详细

【剑指offer】面试题14、调整数组顺序使奇数位于偶数前面

时间:2015-06-19 21:36:22      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

题目:输入一个整数数组,实现一个函数来解决该数组中数字的位置,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

本题思路较为简单,我们只需维护两个指针:第一个指针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

 

本文完。

【剑指offer】面试题14、调整数组顺序使奇数位于偶数前面

标签:

原文地址:http://www.cnblogs.com/xfxu/p/4586052.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!