数组分区与双指针交换法介绍
数组分区的概念:
其实就是指将数组的元素分为两部分,比如:分为偶数与奇数,分为非数字字符与数字字符,分为质数与非质数,分为大于 指定值的数,和小于指定值的数。
双指针交换法介绍:
由于需要分区,我们呢往往需要最快的分区速度,而仅需一次遍历就能完成分区操作,无需移动数组排列的双指针交换法 接受了这个任务。
原理:
假如满足条件的元素(假设条件是奇数)在左区,不满足条件的元素(偶数)在右区,那么我们的思路就是:
双指针: pLeft = 0 , pRight = arr.size -1
- pLeft 从左至右遍历,当碰到不满足条件的元素,我们暂停 pLeft 移动
- pRight 从右至左遍历,当碰到满足条件的元素,我们暂停 pRight 移动
- 交换两个指针指向的元素
- 重复 1,2,3 步骤
图例:
编写进行分区操作的双指针交换法,考虑可扩展性
我们需要两个函数来完成双指针交换法:
- 判断数字应该是属于数组前半部分还是后半部分的标准 : bool isEven(int n)
- 拆分数组的操作 : void Recorder(int *pData,unsigned int length,bool (*func)(int))
测试样例:
功能测试:使用交替的满足条件和不满足的元素,输入数组中所有满足条件的元素都在后面,不满足的都在前面的数组。
特殊输入测试:nullptr指针,输入的数组只包含一个数字。
扫描二维码关注公众号,回复:
11382563 查看本文章
//这里我们使用 函数指针 来传递函数,分区判断的标准
bool isEven(int n)
{
// 分区判断内容,比如奇数偶数判断
return (n & 0x1) == 0; //偶数返回真,奇数返回假
}
void Recorder(int *pData,unsigned int length,bool (*func)(int)){
if(pData == nullptr || length==0 )
return;
int *pBegin = pData;
int *pEnd = pData + length -1;
while(pBegin < pEnd){
while(pBegin < pEnd && func(*pBegin))
++ pBegin;
while(pBegin < pEnd && !func(*pEnd))
-- pEnd;
if(pBegin < pEnd)
swap(*pBegin,*pEnd);
}
}