题目14 调整数组顺序使奇数位于偶数前面

/////////////////////////////////////////////////////////////////////////////////////
// 4. 题目14 调整数组顺序使奇数位于偶数前面



//方法一:时间复杂度O(n),空间复杂度O(n) 而且数据是没有顺序的!!!!
void ReorderArray(int aiArray[], int iLen)
{
    vector<int> vect(iLen, 0);
    int iStart = 0;
    int iEnd = iLen - 1;
    for (int i = 0; i < iLen; i++)
    {
        // 原则上这里是不会进来的!!!!
        if (iStart > iEnd)
        {
            break;
        }

        // 奇数最后一位肯定是1(二进制)
        if (aiArray[i] & 0x01)
        {
            vect[iStart++] = aiArray[i];
        }
        else
        {
            vect[iEnd--] = aiArray[i];
        }
    }

    for (int i = 0; i < (int)vect.size(); i++)
    {
        aiArray[i] = vect[i];
    }
}


//方法二:只能完成基本功能的解法
//时间复杂度O(n), 空间复杂度O(1)
void ReorderArray_2(int* piData, int iLen)
{
    if (NULL == piData || iLen <= 0)
    {
        return;
    }

    int* piBegin = piData;
    int* piEnd = piData + iLen - 1;

    while (piBegin < piEnd)
    {
        // 向后移动piBegin,直到指向偶数
        while (piBegin < piEnd && (*piBegin & 0x01))
        {
            piBegin++;
        }

        // 向前移动piEnd,直到指向奇数
        while (piBegin < piEnd && !(*piEnd & 0x01))
        {
            piEnd--;
        }

        // 交换值
        if (piBegin < piEnd)
        {
            swap(*piBegin, *piEnd);
        }
    }
}

// 可扩展性
// 1.把数组中的数字按照大小分为两部分,所有负数在非负数前面
void ReorderArray_3(int* piData, int iLen)
{
    if (NULL == piData || iLen <= 0)
    {
        return;
    }

    int* piBegin = piData;
    int* piEnd = piData + iLen - 1;

    while (piBegin < piEnd)
    {
        // 向后移动piBegin,直到指向 > 0
        while (piBegin < piEnd && *piBegin < 0)
        {
            piBegin++;
        }

        // 向前移动piEnd,直到指向 < 0
        while (piBegin < piEnd && *piEnd > 0)
        {
            piEnd--;
        }

        // 交换值
        if (piBegin < piEnd)
        {
            swap(*piBegin, *piEnd);
        }
    }
}

// 扩展2:把数组分为两部分,能被3整除的放到不能被整除的前面
// 类似的解法!!!!
// ....
// 这些扩展只是修改了比较部分!!! 定义一个指针函数

typedef bool(*CMP_FUNC)(int);
void ReorderArray_4(int* piData, int iLen, CMP_FUNC pCmpFunc)
{
    if (NULL == piData || iLen <= 0)
    {
        return;
    }

    int* piBegin = piData;
    int* piEnd = piData + iLen - 1;

    while (piBegin < piEnd)
    {
        while (piBegin < piEnd && !(pCmpFunc(*piBegin)))
        {
            piBegin++;
        }

        while (piBegin < piEnd && pCmpFunc(*piEnd))
        {
            piEnd--;
        }

        if (piBegin < piEnd)
        {
            swap(*piBegin, *piEnd);
        }
    }
}

bool IsEven(int iNum)
{
    return (iNum & 0x01);
}

bool IsNegative(int iNum)
{
    return !(iNum < 0);
}

bool IsDivision(int iNum)
{
    return !(iNum % 3 == 0);
}

void ReorderArrayTestFunc()
{
    cout << "\n\n --------------- ReorderArrayTestFunc Start -------------->" << endl;
    int aiArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
    int aiArray2[] = {1, -2, 3, 4, -5, 6, 7, 8, 9, 10, 11, -12, -13, -14};

    int iLen = sizeof(aiArray) / sizeof(int);
    TRAVERSAL_ARRAY(aiArray, iLen);

    // 数组调整
    cout << "方法一 =====================>>> " << endl;
    ReorderArray(aiArray, iLen);
    TRAVERSAL_ARRAY(aiArray, iLen);

    cout << "方法二 =====================>>> " << endl;
    ReorderArray_2(aiArray2, iLen);
    TRAVERSAL_ARRAY(aiArray2, iLen);

    cout << "扩展一:按大小划分,负数在非负数前面 ==========>>> " << endl;
    ReorderArray_3(aiArray2, iLen);
    TRAVERSAL_ARRAY(aiArray2, iLen);

    cout << "方法三 =====================>>> " << endl;
    ReorderArray_4(aiArray, iLen, IsEven);
    TRAVERSAL_ARRAY(aiArray, iLen);

    cout << "===================扩展一 =============>>>" << endl;
    ReorderArray_4(aiArray2, iLen, IsNegative);
    TRAVERSAL_ARRAY(aiArray2, iLen);

    cout << "===================扩展二 =============>>>" << endl;
    ReorderArray_4(aiArray, iLen, IsDivision);
    TRAVERSAL_ARRAY(aiArray, iLen);

    cout << "\n\n --------------- ReorderArrayTestFunc End -------------->" << endl;

}
posted @ 2019-07-28 13:36  VIP丶可乐  阅读(115)  评论(0编辑  收藏  举报