劍指offer之調(diào)整數(shù)組順序使奇數(shù)位于偶數(shù)前面

1 問題

輸入一個整數(shù)數(shù)組,實現(xiàn)一個函數(shù)來調(diào)整該數(shù)組中數(shù)字的順序,使得所有奇數(shù)位于數(shù)組的前半部分,所有偶數(shù)位于數(shù)組的后半部分,比如數(shù)組{6、 5 、1、 4、2 、7 、3、8、9}我們調(diào)整后變成這樣{9、5、1、3、7 、2 、4 、8、6}   

2 分析

我們利用partition算法博客可以知道,這里還是利用兩個指針,一個指針指向開始,一個指針指向尾巴,分別從兩邊進(jìn)行掃描,我們先從尾巴指針向左移動,發(fā)現(xiàn)了奇數(shù)就暫停這里,然后開始移動首指針,如果發(fā)現(xiàn)是偶數(shù)了就保存當(dāng)前指針,然后和之前掃描到奇數(shù)位置進(jìn)行換位置,終止條件是首指針的值等于尾指針的值。

 
3 代碼實現(xiàn)

    #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;
    }
     
    /*
     *奇數(shù)在偶數(shù)前面的函數(shù)
     */
    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 運行結(jié)果

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

 
5 優(yōu)化

比如我們還有類似的問題,比如數(shù)組里面有負(fù)數(shù)和整數(shù),我們要求負(fù)數(shù)在正數(shù)前面,我么知道reorderOddEven函數(shù)里面只要把(vector[start] % 2) != 0這個條件進(jìn)行修改就行,這里我么可以使用函數(shù)指針,根據(jù)不同的需求傳遞不同的函數(shù)指針下來,達(dá)到效果,增加部分代碼實現(xiàn)如下。

    #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;
    }

運行結(jié)果如下

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

如果我們要實現(xiàn)負(fù)數(shù)在前面的數(shù)組,我們只需要調(diào)用reorderOddEvenOne函數(shù)傳遞isNagetiveNumber作為函數(shù)指針就行。



作者:chen.yu
深信服三年半工作經(jīng)驗,目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號:編程入門到禿頭 或掃描下面二維碼
零基礎(chǔ)入門進(jìn)階人工智能(鏈接)