《剑指offer》第二十一题:调整数组顺序使奇数位于偶数前面

Posted zsy-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指offer》第二十一题:调整数组顺序使奇数位于偶数前面相关的知识,希望对你有一定的参考价值。

// 面试题21:调整数组顺序使奇数位于偶数前面
// 题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有
// 奇数位于数组的前半部分,所有偶数位于数组的后半部分。

#include <cstdio>

void Reorder(int* pData, unsigned int length, bool (*func)(int));
bool isEven(int n);

// ====================方法一====================
void ReorderOddEven_1(int* pData, unsigned int length)
{
    //鲁棒性检测
    if (pData == nullptr || length == 0)
        return;

    //主要思路:指针1寻找前半部分的偶数,指针2寻找后半部分的奇数,然后交换
    int* pBegin = pData;
    int* pEnd = pData + length - 1;

    while (pBegin < pEnd)
    {
        //寻找前半部分的偶数
        while (pBegin < pEnd && (*pBegin & 0x1) != 0)
            ++pBegin;
        //寻找后半部分的奇数
        while (pBegin < pEnd && (*pEnd & 0x1) == 0)
            --pEnd;

        if (pBegin < pEnd)
        {
            //交换两个指针内容
            int temp = *pBegin;
            *pBegin = *pEnd;
            *pEnd = temp;
        }
    }
}

// ====================方法二====================
void ReorderOddEven_2(int* pData, unsigned int length)
{
    Reorder(pData, length, isEven);
}

void Reorder(int* pData, unsigned int length, bool (*func)(int)) //函数地址
{
    if (pData == nullptr || length == 0)
        return;

    int* pBegin = pData;
    int* pEnd = pData + length - 1;

    if (pBegin < pEnd)
    {
        while (pBegin < pEnd && !func(*pBegin))
            ++pBegin;
        while (pBegin < pEnd && func(*pEnd))
            --pEnd;

        if (pBegin < pEnd)
        {
            int temp = *pBegin;
            *pBegin = *pEnd;
            *pEnd = temp;
        }
    }
}

bool isEven(int n)
{
    //是否为偶数
    return (n & 0x1) == 0;
}
技术图片
// ====================测试代码====================
void PrintArray(int numbers[], int length)
{
    if (length < 0)
        return;

    for (int i = 0; i < length; ++i)
        printf("%d	", numbers[i]);

    printf("
");
}

void Test(const char* testName, int numbers[], int length)
{
    if (testName != nullptr)
        printf("%s begins:
", testName);

    int* copy = new int[length];
    for (int i = 0; i < length; ++i)
    {
        copy[i] = numbers[i];
    }

    printf("Test for solution 1:
");
    PrintArray(numbers, length);
    ReorderOddEven_1(numbers, length);
    PrintArray(numbers, length);

    printf("Test for solution 2:
");
    PrintArray(copy, length);
    ReorderOddEven_2(copy, length);
    PrintArray(copy, length);

    delete[] copy;
}

void Test1()
{
    int numbers[] = { 1, 2, 3, 4, 5, 6, 7 };
    Test("Test1", numbers, sizeof(numbers) / sizeof(int));
}

void Test2()
{
    int numbers[] = { 2, 4, 6, 1, 3, 5, 7 };
    Test("Test2", numbers, sizeof(numbers) / sizeof(int));
}

void Test3()
{
    int numbers[] = { 1, 3, 5, 7, 2, 4, 6 };
    Test("Test3", numbers, sizeof(numbers) / sizeof(int));
}

void Test4()
{
    int numbers[] = { 1 };
    Test("Test4", numbers, sizeof(numbers) / sizeof(int));
}

void Test5()
{
    int numbers[] = { 2 };
    Test("Test5", numbers, sizeof(numbers) / sizeof(int));
}

void Test6()
{
    Test("Test6", nullptr, 0);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();

    return 0;
}
测试代码

分析:两个指针进行操作,将函数模块化,传入函数地址。

 

以上是关于《剑指offer》第二十一题:调整数组顺序使奇数位于偶数前面的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer(Java版)第二十一题:链表中环的入口结点

乱序版 ● 剑指offer每日算法题打卡题解—— 双指针(题号21,57,58)

每日一题 为了工作 2020 0323 第二十一题

剑指offer二十一之栈的压入弹出序列

《剑指Offer》题十一~题二十

《剑指offer》第五十一题(数组中的逆序对)