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

来源:互联网 发布:java基础教程视频下载 编辑:程序博客网 时间:2024/06/01 09:30

一个简单的交换两个数值的函数可以这么写:

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]变成零。



0 0
原创粉丝点击