剑指offer-----021(调整数组顺序使奇数位于偶数前面)

更多题目:《 剑指offer》 目录索引

题目描述:

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

方法一:

  1. 利用左右指针,left和right。left指向数组首元素,right指向数组尾元素。

  2. 左指针从左往右找,找到偶数停止

  3. 右指针从右往左找,找到奇数停止
  4. 交换左右指针的元素
  5. 当左右指针分别指向数组中的最后一个奇数和偶数时,数组调整完毕

这里写图片描述

代码:

void Reorder(int *pData, unsigned int length)
{
    if (pData == NULL || length < 0)
        return;

    int* start = pData;//第一个
    int* finish = pData +length - 1;//最后一个

    while (start < finish)
    {
        while (start < finish && ((*start & 1) != 0))//找到偶数就停止
        {
            start++;
        }

        while (start < finish && ((*finish & 1) == 0))//找到奇数就停
        {
            finish--;
        }

        if (start < finish)
        {
            int tmp = *start;
            *start = *finish;
            *finish = tmp;
        }
    }

}

方法二:

 上述方法中,利用左右指针找到奇数和偶数,并且采用&操作符进行判断,但这有一个缺陷,只能解决奇数和偶数的问题,但此题还有很多扩展题目,例如:负数和非负数,素数和合数。。。。。。此时,我们需要将其判断条件封装成一个函数,以后改变判断条件即可,就可解决不同的扩展题目

代码:


//偶数返回0,奇数返回1
bool isEven(int n)
{
    return (n&1)== 0;
}

void Reorder1(int *pData, unsigned int length, bool(*func)(int))
{

    if (pData == NULL || length < 0)
        return;

    int* start = pData;//第一个
    int* finish = pData + length - 1;//最后一个

    while (start < finish)
    {
        while (start < finish && !func(*start))//找到偶数就停止
        {
            start++;
        }

        while (start < finish && func(*finish))//找到奇数就停
        {
            finish--;
        }

        if (start < finish)
        {
            int tmp = *start;
            *start = *finish;
            *finish = tmp;
        }
    }
}

测试用例:

// ====================测试代码====================
void PrintArray(int numbers[], int length)
{
    if (length < 0)
        return;

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

    printf("\n");
}

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

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

    printf("Test for solution 1:\n");
    PrintArray(numbers, length);
    Reorder1(numbers, length, isEven);
    PrintArray(numbers, length);
    printf("\n\n");
    printf("Test for solution 2:\n");
    PrintArray(copy, length);
    Reorder1(copy, length, isEven);
    PrintArray(copy, length);
    printf("\n************************************************************\n");
    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();

    system("pause");
    return 0;
}


结果:

这里写图片描述

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zhangye3017/article/details/80214201