您的位置:首页 > 其它

数组中用异或进行数值交换需要注意的问题

2015-08-13 11:02 441 查看
一个简单的交换两个数值的函数可以这么写:

void swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}


高级一点的可以这么写:

void swap(int x, int y)
{
x = x^y;
y = x^y;
x = x^y;
}


到现在为止对于交换两个数的值完全没有问题。
但是,当需要交换数组中的两个值时,第二种写法就存在bug。函数如下:

void swap(int[] array, int i, int j)
{
//i,j为需要交换数值的数组下标

array[i] = array[i]^array[j];
array[j] = array[i]^array[j];
array[i] = array[i]^array[j];
}




对于某些排序算法,如快排,在算法运行的过程中可能会交换两个相同下标的值,这时的函数调用就会出现swap(array,i,i)的情况,
如果swap函数是第二种实现,根据异或的运算规则---两个相同的数异或结果为0---就会把array[i]的值变成零。

所以正确写法如下:

void swap(int[] array, int i, int j)
{
//i,j为需要交换数值的数组下标
if(i == j)
return;//下标相同直接返回
array[i] = array[i]^array[j];
array[j] = array[i]^array[j];
array[i] = array[i]^array[j];
}


快排中的partition函数可能出现交换相同下标值,代码如下:

int partition(int[] array, int start, int end)
{
int pivot = array[end];
int i = start - 1;
for(int j = start;j<end;j++)
{
if(array[j] < pivot)
{
i++;
swap(array,i,j);//行1
}
}

i++;
swap(array,i,end);
return i;
}
根据以上代码,当数组中的第一个数比最后一个数(即pivot)小的时候(如array = {1,2,3,})就会出现调用swap(array,0,0)的情况,从而导致array[0]变成零。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: