剑指offer——使数组中奇数全部位于偶数前面

从前往后找所要交换的两个数

void ReOrder(int* arr, int size)
{
    if (arr == NULL || size <= 1)return;
    int i = 0,j = 0;
    while (i < size&&j < size){
        while (i < size && ((arr[i] & 0x01) == 1)){//找偶数
            ++i;
        }
        while (j < size && ((arr[j] & 0x01) == 0)){//找奇数
            ++j;
        }
        if (i < size&&j < size){
            if (i < j)//保证所找到的奇数在偶数的后面才进行交换
                swap(arr[i], arr[j]);
            else//否则继续找下一个奇数
                ++j;
        }
    }
}

扩展性代码

只需要根据不同的需求实现solution()方法即可,_ReorderOddEven()函数可以被复用

//奇数放到偶数前面
bool solution(int n)
{
    if ((n & 0x01) == 0)//n是偶数
        return false;
    else
        return true;
}
//负数在非负数前面
bool solution2(int n)
{
    if (n < 0)
        return true;
    else
        return false;
}
//能被3整除的在前面,不能被3整除的数在后面
bool solution3(int n)
{
    if (n % 3 == 0)
        return true;
    else
        return false;
}
void _ReorderOddEven(int* arr, int size, bool(*Fun)(int))
{
    int* start = arr;
    int* end = start + size - 1;
    while (start < end){
        while (start < end && Fun(*start)){
            ++start;
        }
        while (start < end && !Fun(*end)){
            --end;
        }
        if (start < end){
            swap(*start, *end);
            ++start, --end;
        }
    }
}
void ReorderOddEven(int* arr, int size)
{
    if (arr == NULL || size <= 1)return;
    bool(*fun)(int);
    fun = &solution;
    _ReorderOddEven(arr, size,fun);
}
void ReorderOddEven2(int* arr, int size)
{
    if (arr == NULL || size <= 1)return;
    bool(*fun)(int);
    fun = &solution2;
    _ReorderOddEven(arr, size, fun);
}
void ReorderOddEven3(int* arr, int size)
{
    if (arr == NULL || size <= 1)return;
    bool(*fun)(int);
    fun = &solution3;
    _ReorderOddEven(arr, size, fun);
}
int main()
{
    /*int arr[] = { 1, 2, 3, 4, 5, 6, 20, 7, 19, 99, 100, 101 };
    ReorderOddEven(arr, sizeof(arr) / sizeof(arr[0]));
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i){
        cout << arr[i] << " ";
    }*/

    /*int arr2[] = { -1, -5, 3, 7, 29, -4, 0, 98, -5 };
    ReorderOddEven2(arr2, sizeof(arr2) / sizeof(arr2[0]));
    for (int i = 0; i < sizeof(arr2) / sizeof(arr2[0]); ++i){
        cout << arr2[i] << " ";
    }*/

    int arr3[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    ReorderOddEven3(arr3, sizeof(arr3) / sizeof(arr3[0]));
    for (int i = 0; i < sizeof(arr3) / sizeof(arr3[0]); ++i){
        cout << arr3[i] << " ";
    }

    system("pause");
}

《完》

时间: 2024-10-01 02:27:44

剑指offer——使数组中奇数全部位于偶数前面的相关文章

剑指offer (36) 数组中的逆序对

题目:在数组中的两个数字如果前面一个数字大于后面一个数字,则这两个数字组成一个逆序对 题解分析: 首先应该想到很简单的一种解法,顺序遍历数组,对每个数,逐个比较该数字和其以后的数字,T(n) = O(n^2) (1)总体的意思就是将数组分成两段,首先求段内的逆序对数量,比如下面两段代码就是求左右两端数组段内的逆序对数量 count += Merge(data, temp, first, mid);//找左半段的逆序对数目 count += Merge(data, temp, mid + 1, e

【剑指offer】数组中只出现一次的数字(1)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 每个测试案例包括两行: 第一行包含一个整数n,表示数组大小.2<=n <= 10^6. 第二行包含n个整数,表示数组元素,元素均为int. 输出: 对应每个测试案例,输出数组中只出现一次的两个数.输出的数字从小到大的顺序. 样例输入: 8 2 4 3 6 3

【剑指offer】数组中的逆序对

# @left part: [start, mid] # @right part: (mid, end] def merge(data, start, mid, end): if mid < start or end < mid: return 0 reverse = 0 ''' @ for start, it play as the start index of left part, and mid @ play as the end index of left part; @ mid +

剑指OFFER之数组中出现次数超过一半的数字(九度OJ1370)

题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 输入: 每个测试案例包括2行: 第一行输入一个整数n(1<=n<=100000),表示数组中元素的个数. 第二行输入n个整数,表示数组中的每个元素,这n个整数的范围是[1,1000000000]. 输出: 对应每个测试案例,输出出现的次数超过数组长度的一半的数,如果没有输出-1. 样例输入:

剑指offer (29) 数组中出现次数超过一半或1/3或1/N的数字

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字 方法一:如果把这个数字排序,那么排序之后位于数组中间的数字一定就是出现次数超过数组长度一半的数字 这个数字就是统计学中的中位数,即长度为n的数组中第n/2大的数字 在数组中得到任意第k大数字,这一问题有O(n)解,注:这里第kth个元素,kth从1开始计数,并且重复元素不去重 (1) 直接sort排序,然后定位到索引为kth-1的元素 int FindKth1(std::vector<int>& num, int kt

【剑指offer】数组中仅仅出现一次的数字(1)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描写叙述: 一个整型数组里除了两个数字之外,其它的数字都出现了两次.请敲代码找出这两个仅仅出现一次的数字. 输入: 每一个測试案例包括两行: 第一行包括一个整数n,表示数组大小.2<=n <= 10^6. 第二行包括n个整数,表示数组元素,元素均为int. 输出: 相应每一个測试案例.输出数组中仅仅出现一次的两个数.输出的数字从小到大的顺序. 例子输入: 8 2 4

[剑指Offer]40.数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 我们直到异或的性质: 任何一个数字异或他自己都等于0. 所以说我们如果从头到尾依次异或每一个数字,那么最终的结果刚好只出现一次的数字,因为成对出现的两次的数字全部在异或中抵消了. 这道题中有两个数字只出现一次.这样的话我们得到的结果就是这两个数字的异或结果.因此我们想办法把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字.这样我们就可以对这两个子数组分别异或,就能得到两个只出现一

【Java】 剑指offer(39) 数组中出现次数超过一半的数字

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1, 2, 3, 2, 2, 2, 5, 4, 2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 思路 思路一:数字次数超过一半,则说明:排序之后数组中间的数字一定就是所求的数字. 利用partition()函数获得某一随机数字,其余数字按大小排在该数字的左右.若该

【Java】 剑指offer(51)数组中的逆序对

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路 如果遍历数组,对每个数字都和后面的数字比较大小,时间复杂度为O(n^2),效率太低. 利用归并排序的思想,先将数组分解成为n个长度为1的子数组,然后进行两两合并同时排好顺序. 在对两个子区域合并排序时,记左边区域(下标为start~mid)的指针