#数据结构与算法学习笔记#剑指Offer12:调整数组顺序使奇数位于偶数之前原版+升级版+测试用例(Java、C/C++)

2018.8.8

这道题原版是不要求调整后的元素相对顺序与原序列一致的,那其实就可以用首尾对称调换的方法做。后面C++的代码是按原题做的标准答案。现在要求调整后的元素相对顺序与原序列一致,也不难。

思路一:奇偶两个flag point从头出发,oddpoint停在第一个偶数上,evenpoint继续前进到该偶数后的第一个奇数(这么说好像应该两个point名称对调一下,不要在意啦),接着让这两个flag point之间的子序列做一个冒泡,使得奇数冒到最前(如原子序列为6827,冒泡完后为7682)。接着oddpoint前进1格,evenpoint继续前行直到循环结束即可。

思路二:创建一个新数组,遇到偶数就保存到新数组,同时删除原数组中的偶数。最后将新数组中的所有偶数添加到老数组奇数序列后即可。


原版题目描述

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

升级版题目描述

保证奇数和奇数,偶数和偶数之间的相对位置不变。


升级版Java实现(思路一):

/**
 * 
 * @author ChopinXBP 
 * 输入一个整数数组,实现一个函数来调整该数组中数字的顺序
 * 使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
 * 
 *
 */

public class reOrderArray_13 {

	static int[] array = {8, 3, 7, 5, 1};
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Solution(array);
		for(int i = 0;i<array.length;i++){
			System.out.print(array[i]);
		}
	}
	
	public static void Solution(int[] array){
		int oddflag = 0;
		int evenflag = 0;
		
		while(evenflag < array.length){
			//奇偶flag前进到第一个偶数开始进入循环
			if((array[oddflag] & 0x01) == 0){				
				while(evenflag < array.length){
					//将下一个奇数与其之前的所有偶数进行一次冒泡
					if((array[evenflag] & 0x01) == 1){
						Swap(array, oddflag, evenflag);
						oddflag++;
					}
					evenflag++;
				}			
			}
			oddflag++;
			evenflag++;
			
		}
		
	}
	
	public static void Swap(int[]array, int i, int j){
		while(j != i){
			int tmp = array[j - 1];
			array[j - 1] = array[j];
			array[j] = tmp;
			j--;
		}
	}
	

}

升级版C++实现示例(思路二):

//第二个思路:再创建一个数组
class Solution{
public:
    void reOrderArray(vector<int> &array) {
 
        vector<int> array_temp;
        vector<int>::iterator ib1, ie1;
        ib1 = array.begin();
 
 
        for (; ib1 != array.end();){            //遇见偶数,就保存到新数组,同时从原数组中删除
            if (*ib1 % 2 == 0) {
                array_temp.push_back(*ib1);
                ib1 = array.erase(ib1);
            }
            else{
                ib1++;
            }
 
        }
        vector<int>::iterator ib2, ie2;
        ib2 = array_temp.begin();
        ie2 = array_temp.end();
 
        for (; ib2 != ie2; ib2++)             //将新数组的数添加到老数组
        {
            array.push_back(*ib2);
        }
    }
};

原版+测试代码:

#include "stdafx.h"

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

// ====================方法一====================
void ReorderOddEven_1(int *pData, unsigned int length)
{
    if(pData == NULL || length == 0)
        return;

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

    while(pBegin < pEnd)
    {
        // 向后移动pBegin,直到它指向偶数
        while(pBegin < pEnd && (*pBegin & 0x1) != 0)
            pBegin ++;

        // 向前移动pEnd,直到它指向奇数
        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 == NULL || length == 0)
        return;

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

    while(pBegin < pEnd) 
    {
        // 向后移动pBegin
        while(pBegin < pEnd && !func(*pBegin))
            pBegin ++;

        // 向前移动pEnd
        while(pBegin < pEnd && func(*pEnd))
            pEnd --;

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

bool isEven(int n)
{
    return (n & 1) == 0;
}

// ====================测试代码====================
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 != NULL)
        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);
    ReorderOddEven_1(numbers, length);
    PrintArray(numbers, length);

    printf("Test for solution 2:\n");
    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", NULL, 0);
}

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

    return 0;
}

#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#

猜你喜欢

转载自blog.csdn.net/qq_20304723/article/details/81507658