我有一个简单的快速排序函数(我从叔叔"G"那里得到的)
function quicksort( &$list, $l , $r ) {
$i = $l;
$j = $r;
$tmp = $list[(int)( ($l+$r)/2 )];
do {
while( $list[$i] < $tmp )
$i++;
while( $tmp < $list[$j] )
$j--;
if( $i <= $j ) {
$w = $list[$i];
$list[$i] = $list[$j];
$list[$j] = $w;
//_swp($list[$i],$list[$j]);
$i++;
$j--;
}
}while( $i <= $j );
if( $l < $j )
quicksort($list, $l, $j);
if( $i < $r )
quicksort($list, $i, $r);
return $list;
}
我有一个小函数来交换两个变量。
function _swp(&$a,&$b){
$a=$a+$b;
$b=$a-$b;
$a=$a-$b;
}
为什么我不能在quicksort
函数中使用_swp($a,$b)来代替这几行?
$w = $list[$i];
$list[$i] = $list[$j];
$list[$j] = $w;
如果我注释掉这3行代码并输入对_swp函数的调用,我会得到糟糕的结果
请解释
向致以最良好的问候
意外行为可能是排序列表中"随机"出现零。发生这种情况是因为在交换时有一种特殊情况:
if( $i <= $j ) {
// swapping here using references!
_swp($list[$i],$list[$j]);
$i++;
$j--;
}
问题直接出现在交换自身的条件中:if $i==$j
则有两个对同一变量的引用。因此,调用_swp($list[$i],$list[$j]);
将首先添加两个变量$a = $a + $b
。考虑到$a和$b实际上访问相同的变量内容,那么$a和$b将具有相同的值。在下一步骤中,$b = $a - $b
将为零,因为$a等于$b。第三个操作将把结果留给0。
一个简单的解决方案是插入另一个条件:
if( $i <= $j ) {
// ensure $i to be truly smaller than $j
if( $i < $j ) {
_swp($list[$i],$list[$j]);
}
$i++;
$j--;
}
我希望这对你有帮助。干杯Fabian