在 QuickSort 中交换两个变量时会发生奇怪的事情
Strange things happen when swapping two vars in QuickSort
我正在用 C 实现 QuickSort。
这是我的交换程序:
void swap(int *x, int *y)
{
*x += (*y);
*y = (*x) - (*y);
*x = (*x) - (*y);
}
这是我的分区程序:
int partition(int a[], int sx, int dx)
{
int indice_pivot = (rand()%(dx-sx+1))+sx;
int i = sx-1, j;
swap(&a[indice_pivot],&a[dx]);
for(j=sx;j<dx;j++)
{
if(a[j] <= a[dx])
{
i++;
swap(&a[j],&a[i]);
}
}
i++;
swap(&a[i],&a[dx]);
return i;
}
问题是当交换两个变量时,它们神奇地(?)变成了 0。我进行了一些调试,交换过程中的一切似乎都运行良好。但是数组在某些分区(不是全部)的末尾包含零。
奇怪的是,如果我用
替换交换过程
void swap(int *x, int *y)
{
int temp = *y;
*y = *x;
*x = temp;
}
一切正常。为什么?
交换(...)
- 有符号整数溢出未定义,
*x
和 *y
足够大时会发生。
- 绝对没有人能轻易判断实现
swap()
的代码是否正确。
分区(...)
- 如果
i == j
,您的 swap() 函数将无法正常工作。这是因为在 swap()
中我们将有 x == y
而你的逻辑不处理这种情况。
如果两个指针都指向同一个元素,您的交换函数将不起作用。如果他们执行第二步 *y = (*x) - (*y);
将元素设置为 0,因为它等同于 *x = (*x) - (*x);
带有临时变量的第二个交换函数保留值。
乍看之下,swap(&a[indice_pivot],&a[dx]);
可能命中了同一个元素。您可以使用 assert( indice_pivot != dx )
来确定(或者当然在交换函数中放入一个)。
我正在用 C 实现 QuickSort。
这是我的交换程序:
void swap(int *x, int *y)
{
*x += (*y);
*y = (*x) - (*y);
*x = (*x) - (*y);
}
这是我的分区程序:
int partition(int a[], int sx, int dx)
{
int indice_pivot = (rand()%(dx-sx+1))+sx;
int i = sx-1, j;
swap(&a[indice_pivot],&a[dx]);
for(j=sx;j<dx;j++)
{
if(a[j] <= a[dx])
{
i++;
swap(&a[j],&a[i]);
}
}
i++;
swap(&a[i],&a[dx]);
return i;
}
问题是当交换两个变量时,它们神奇地(?)变成了 0。我进行了一些调试,交换过程中的一切似乎都运行良好。但是数组在某些分区(不是全部)的末尾包含零。 奇怪的是,如果我用
替换交换过程void swap(int *x, int *y)
{
int temp = *y;
*y = *x;
*x = temp;
}
一切正常。为什么?
交换(...)
- 有符号整数溢出未定义,
*x
和*y
足够大时会发生。 - 绝对没有人能轻易判断实现
swap()
的代码是否正确。
分区(...)
- 如果
i == j
,您的 swap() 函数将无法正常工作。这是因为在swap()
中我们将有x == y
而你的逻辑不处理这种情况。
如果两个指针都指向同一个元素,您的交换函数将不起作用。如果他们执行第二步 *y = (*x) - (*y);
将元素设置为 0,因为它等同于 *x = (*x) - (*x);
带有临时变量的第二个交换函数保留值。
乍看之下,swap(&a[indice_pivot],&a[dx]);
可能命中了同一个元素。您可以使用 assert( indice_pivot != dx )
来确定(或者当然在交换函数中放入一个)。