[C言語 - 二分法] バイナリメソッドを使用して順序付き配列内の数値の添え字を見つけるには、なぜmid+1、mid-1が必要なのでしょうか?

まずコード全体を貼り付けます。

#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 ではないため、ループから抜け出します。

 

 

おすすめ

転載: blog.csdn.net/ggbb_4/article/details/129126836