剑指offer(5)-调整数组顺序使得奇数位于偶数之前

来源:互联网 发布:vue.js面试题 编辑:程序博客网 时间:2024/05/21 07:53

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

拿到题目之后,暴力方法很快就可以想到,只要从头遍历数组,遇到偶数后就提取出来,把后面的元素向前移动一位,将取出的数放到数组最后的空位就好了,这样做的话遍历数组的寻找偶数需要O(n)时间,移动数组又需要O(n)时间,总的时间就是O(n^2),意义不大。

一种稍微复杂一点的方法有可能想到,用排序的方法去处理,用两个指针分别指向数组开头和末尾,设为firstOdd和endEven,指针分别向中间扫,若遇见firstOdd指向偶数,并且endEven指向奇数就交换指向的值,否则就firstOdd++,endEven–,直到endEven跑到firstOdd前面,交换过程也就结束了。

// ReOrderOddEven.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<iostream>using namespace std;void ReOrderOddEven(int *arr, unsigned int length){    if(arr == NULL || 0 == length)    return;    int *firstOdd;    int *endEven;    firstOdd = &arr[0];    endEven = &arr[length - 1];    while (firstOdd < endEven)    {        while (*firstOdd % 2 == 1)        {            firstOdd++;        }        while (*endEven % 2 == 0)        {            endEven--;        }        if (firstOdd < endEven )        {            int temp = *firstOdd;            *firstOdd = *endEven;            *endEven = temp;        }    }}int main(){    cout << "array = {1,2,3,4,5,6,7,8,9,10}";    cout << endl;    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };    ReOrderOddEven(arr, 10);    for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++){        cout << arr[i] << " ";}    return 0;}

作者用函数指针增加了代码的可重用性:

void ReOrder(int *arr, unsigned int length, bool (*pf)(int)) {    if  (0 == length || arr == NULL)        return;    int *firstOdd;    int *endEven;    firstOdd = &arr[0];    endEven = &arr[length - 1];    while (firstOdd < endEven)    {        while (firstOdd < endEven && !(pf(*firstOdd)))        {            firstOdd++;        }        while (firstOdd < endEven && (pf(*endEven)))        {            endEven--;        }        if (firstOdd < endEven)        {            int temp = *firstOdd;            *firstOdd = *endEven;            *endEven = temp;        }    }}bool isEven(int n){    return (n & 1 == 0);}void ReOrderOddEven(int *arr, unsigned int length){    ReOrder(arr, length, isEven);}
0 0
原创粉丝点击