2-2
题干

答案
(1)

当 x > middle 时,left = middle 和 x < middle 时,right = middle 错误,在特定条件下会导致死循环。当 right - left = 1 时,middle = (left + right) / 2 = left,此时如果 x > a[middle],left = middle,相当于没有改变 left ,此时会导致死循环。且数组中找不到 x 时也会出现死循环,因为此时 left <= right 恒成立。
举例,考虑数组{1, 2},其中 n=2,要查找 x=2。初始时 left=0,right=1,进入 while 循环后 middle=(0+1)/2=0 ,x=2 > a[0]=1,所以设置 left=middle=0,区间仍为[0,1],left 和 right 都没有更新,陷入死循环。
正确的代码片段应该为
if (x == a[middle])
return middle;
if (x > a[middle])
left = middle + 1;
else
right = middle - 1;
(2)


只判断 x == left 错误,会导致当 x == a[n-1] 时返回 -1。当要找的 x 恰好在数组末尾时,因为 left < right - 1,所以 middle < right,不会走 x < a[middle] 分支,所以 right 保持在 n-1 不会变,只有 left 在增大缩小范围。当 left == right - 1 时退出循环,然后检查 x == left,不符合,就返回 -1 了。这会导致当 x == a[n-1] 时返回 -1。
举例,还是考虑数组{1, 2},其中 n=2,要查找 x=2。初始时 left=0,right=1,不满足循环条件,检查 x = 2 != a[middle] = 1,所以走 else 分支,返回 -1,没有找到数组中有的 x。
正确的代码片段应该为
if (x == a[left])
return left;
else if (x == a[right)
return right;
else
return -1;
(3)

与(2)有一样的错误,而且当 n=1 时会出现死循环。因为 n=1 时,初始化 left = right = 0,恒满足 left + 1 != right,所以会导致死循环问题。
正确的代码片段参考(2)。
(4)


middle = (left+right)/2 错误,在特定条件下会导致死循环。当 right - left = 1 时,middle = (left + right) / 2 = left,此时如果 x >= a[middle],left = middle,相当于没有改变 left ,此时会导致死循环。且数组中找不到 x 且 x > a[middle] 时也会出现死循环,原因和前面一样,left 永远不变。
举例参考(1)。
正确的代码片段应该为
int middle = (left + right + 1) / 2;
(5)

正确。因为
1972

被折叠的 条评论
为什么被折叠?



