• 【剑指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("
    ");
    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("
    ");
    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

    本文完。

  • 相关阅读:
    wxWidgets教程
    Unity游戏资源反解工具
    The Story About .NET Cross Platform UI Frameworks
    IMGUI
    Unity可编程管线的顶点光照Shader
    常用mac命令
    Vulkan相关资源
    Controlling fixed function states from materials/scripts in Unity
    Forward Rendering VS Deferred Rendering
    C#转PHP
  • 原文地址:https://www.cnblogs.com/xfxu/p/4586052.html
Copyright © 2020-2023  润新知