有一个整数数组,我们想按照特定规则对数组中的元素进行排序,比如:数组中的所有奇数位于数组的前半部分。

本文将带大家实现这个算法,欢迎各位感兴趣的开发者阅读本文。

通过观察后,我们发现在扫描这个数组的时候,如果发现有偶数出现在奇数的前面, 就交换他们的顺序,交换之后就符合要求了。

因此,我们可以维护两个指针:

第一个指针初始化时指向数组的第一个数字,它只向后移动;

第二个指针初始化时指向数组的最后一个数字,它只向前移动;

在两个指针相遇之前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是偶数,并且第二个指针指向的数字是奇数,则交换这两个数字。

接下来,我们来通过图来描述下上述例子交换指针的过程,如下所示:

第一个指针永远指向偶数,如果不为偶数就向后移动;

第二个指针永远指向奇数,如果不为奇数就向前移动;

当两个指针各自指向的数都符合条件时,就交换两个元素的位置;

交换完成后,重复上述步骤,直至两个指针相遇或者第一个指针位于第二个指针之后则代表问题已得到解决。

有了思路之后,我们来看下实现代码,如下所示:

如果数组中的元素不按照奇前偶后排列,我们需要将其按照大小进行划分,所有负数都排在非负数的前面,应该怎么做?

聪明的开发者可能已经想到了方案:双指针的思路还是不变,我们只需修改内层while循环的的判断条件即可。

这样回答没有问题,确实解决了这个问题,那么如果再改改题目,我们需要把数组中的元素分为两部分,能被3整除的数都在不能被3整除的数前面,应该怎么做?

经过思考后,我们发现这个问题无论再怎么改变都有一个共同的部分:双指针的逻辑永远不会变。变化的只是判断条件,那么我们就可以把变化的部分提取成函数,当作参数让调用者传进来,这样就完美的解决了这个问题,也正是我们所提及的代码的可扩展性。

最后,我们来看下实现代码,如下所示:

我们先来测试下奇数在偶数之前的函数处理代码能否正常执行,如下所示:

最后,我们来测试下reorder函数能否正常执行: