まずコード全体を貼り付けます。
#include<stdio.h>
int two_search(int arr[], int length, int k)
{
int left = 0;
int right = length - 1;
while (left <= right)
{
int mid = (right + left) / 2; //(0+9)/2=4
if (k > arr[mid])
left = mid+1; //加1 减1 是必须的
else if (k < arr[mid])
right = mid-1;
else
return mid;
}
return -1;
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int k = 11; //想查找的数的下标
int length = sizeof(arr) / sizeof(arr[0]);
int ret = two_search(arr,length,k);
if (ret != -1)
printf("找到,%d在数组中的下标为%d", k, ret);
else
printf("未找到");
return 0;
}
質問: ここの Mid に 1 が加算されるのはなぜですか?
while (left <= right)
{
int mid = (right + left) / 2; //(0+9)/2=4
if (k > arr[mid])
left = mid+1; //加1 减1 是必须的
else if (k < arr[mid])
right = mid-1;
else
return mid;
}
分析します:
Mid が加算演算を使用しない場合:
たとえば、12345678910 から 8 を検索すると、結果は正しくなります。
11 を検索すると、問題が発生します。
結果は明らかに見つかりませんが、プログラムは実行を続け、終了できません。
理由:
left は left=8 になるまで右に移動し続けます。このとき、right=9、mid=(8+9)/2=8 なので、left は常に 8 になります。同時に、ループ本体の状態に注目してください。 while (left <= right) の場合、left は常に right より小さいため、プログラムはループから抜け出すことができず、無限ループが発生します。図に示すように:
Mid が add 1 操作を使用する場合:
left=8 になるまで left は右に移動し続けます。このとき、right=9、mid=(8+9)=8 がさらに更新され、left=mid+1=9 となり、左が右と交差するまで、 while() は true ではないため、ループから抜け出します。