剑指offer之调整数组顺序使奇数位于偶数前面

1 问题

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分,比如数组{6、 5 、1、 4、2 、7 、3、8、9}我们调整后变成这样{9、5、1、3、7 、2 、4 、8、6}   

2 分析

我们利用partition算法博客可以知道,这里还是利用两个指针,一个指针指向开始,一个指针指向尾巴,分别从两边进行扫描,我们先从尾巴指针向左移动,发现了奇数就暂停这里,然后开始移动首指针,如果发现是偶数了就保存当前指针,然后和之前扫描到奇数位置进行换位置,终止条件是首指针的值等于尾指针的值。

 
3 代码实现

    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    void swap(int* a, int* b)
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
     
    void printVector(vector<int> v)
    {
        for (int i = 0; i < v.size(); ++i)
        {
            std::cout << v[i] << "\t";
        }
        std::cout << std::endl;
    }
     
    /*
     *奇数在偶数前面的函数
     */
    void reorderOddEven(vector<int>& vector)
    {
        if (vector.size() <= 0)
        {
            std::cout << "vector.size is <= 0" << std::endl;
            return;
        }
        int start = 0;
        int end = vector.size() - 1;
        while (start < end)
        {
            while (start < end && (vector[end] % 2) == 0)
            {
                --end;
            }
            while (start < end &&  (vector[start] % 2) != 0)
            {
                ++start;   
            }
            swap(vector[start], vector[end]);
        }
    }
     
    int main()
    {
        vector<int> v2;
        v2.push_back(6);
        v2.push_back(5);
        v2.push_back(1);
        v2.push_back(4);
        v2.push_back(2);
        v2.push_back(7);
        v2.push_back(3);
        v2.push_back(8);
        v2.push_back(9);
        
        vector<int> v3;
        printVector(v2);
        reorderOddEven(v2);
        printVector(v2);
        
        return 0;
    }


 
4 运行结果

    6    5    1    4    2    7    3    8    9   
    9    5    1    3    7    2    4    8    6   

 
5 优化

比如我们还有类似的问题,比如数组里面有负数和整数,我们要求负数在正数前面,我么知道reorderOddEven函数里面只要把(vector[start] % 2) != 0这个条件进行修改就行,这里我么可以使用函数指针,根据不同的需求传递不同的函数指针下来,达到效果,增加部分代码实现如下。

    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    void swap(int* a, int* b)
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
     
    void printVector(vector<int> v)
    {
        for (int i = 0; i < v.size(); ++i)
        {
            std::cout << v[i] << "\t";
        }
        std::cout << std::endl;
    }
     
    bool isOddEvenNumber(int number)
    {
        return ((number & 0x1) == 0);
    }
     
     
    bool isNagetiveNumber(int number)
    {
        if (number > 0)
            return true;
        else
            return false;
    }
     
    void reorderOddEvenOne(vector<int>& vector, bool (*func)(int))
    {
        if (vector.size() <= 0)
        {
            std::cout << "vector.size is <= 0" << std::endl;
            return;
        }
        int start = 0;
        int end = vector.size() - 1;
        while (start < end)
        {
            while (start < end && (*func)(vector[end]))
            {
                --end;
            }
            while (start < end && !(*func)(vector[start]))
            {
                ++start;   
            }
            swap(vector[start], vector[end]);
        }
    }
     
     
    int main()
    {
        vector<int> v2;
        v2.push_back(6);
        v2.push_back(5);
        v2.push_back(1);
        v2.push_back(4);
        v2.push_back(2);
        v2.push_back(7);
        v2.push_back(3);
        v2.push_back(8);
        v2.push_back(9);
        
        vector<int> v3;
        printVector(v2);
     
        reorderOddEvenOne(v2, isOddEvenNumber);
        printVector(v2);
     
        return 0;
    }

运行结果如下

    6    5    1    4    2    7    3    8    9   
    9    5    1    3    7    2    4    8    6   

如果我们要实现负数在前面的数组,我们只需要调用reorderOddEvenOne函数传递isNagetiveNumber作为函数指针就行。



作者:chen.yu
深信服三年半工作经验,目前就职游戏厂商,希望能和大家交流和学习,
微信公众号:编程入门到秃头 或扫描下面二维码
零基础入门进阶人工智能(链接)