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

一、问题描述

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

二、解题思路

两个指针,一个首、一个尾。然后一个向前、一个向后判断奇、偶,然后交换(类似于快排的思想)

三、代码实现

void reOrderArray(vector<int> &a)
{
    if(a.empty()) return;
 
    int left = 0;
    int right = a.size()-1;
    while(left < right) //从两边向中间扫描
    {
        //left向后找,直到指向偶数
        while(left<right && a[left]%2 != 0) left++;//若为奇数时,向后移动
        //right向前找,直到指向奇数
        while(left<right && a[right]%2 == 0) right--;//若为偶数,向前移动
        //交换
        swap(a[left], a[right]);
    }
}

但是上述的方法 无法保证调整后,奇数与奇数之间,偶数与偶数之间相对位置不变。此方法和STL的算法partition很像。

如果想保证相对位置问题,需要使用类似于STL的stable_partition算法。

四、STL中的partition和stable_partition算法

这两个方法都用来将指定容器的元素根据指定的predicate函数分成两个子序列,其中满足predicate()函数的,即返回值为true的作为第一个序列[v.begin(), bound), 而[bound, v.end())的作为第二个序列。

两个方法的区别在于, partition()对于两个子序列中的元素并不排序,而stable_partition()则对两个子序列的元素也进行排序。(注意:上面说的排序,不是大小的排序,而是针对于原来的序列的顺序)

1. 两个函数的原型如下:

BidirectionalIterator partition ( BidirectionalIterator first, BidirectionalIterator last, Predicate pred );
BidirectionalIterator stable_partition ( BidirectionalIterator first, BidirectionalIterator last, Predicate pred );
2. 参数的说明如下:

① first, last  第一个和第二个参数说明给定源容器的范围 [first, last)

② pred 第三个参数给定进行分组的规则函数。布尔型返回值 对于返回true的所有元素作为第一个子序列,对于返回false的所有元素作为第二个子序列

pred例子如下:

bool IsOdd(int i)
 {
     return (i%2 == 1);
 }

调用时:

这样的话,奇数在前、偶数在后
bound = partition(v.begin(), v.end(), IsOdd);
//Return value 返回值是 指向第二个子序列的首元素迭代器
cout << "奇数 in the vector are:" <<endl;
     for(it = v.begin(); it != bound; it++)
         cout<<*it<<" ";
 
cout<< "偶数 in the vector are:" <<endl;
     for(it = bound; it != v.end(); it++)
         cout<<*it<<" ";

结果:
奇数 in the vector are: 9 1 7 3 5
偶数 in the vector are: 4 6 2 8 0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值