心胸决定格局,眼界决定境界...

关于二分法 查找的边界问题,大于等于目标值的最小值,小于等于目标值的最大值。

	int a[10] = { 1, 4, 5, 3, 2, 1, 2, 3, 4, 2 };
	sort(a, a + 10);
	//sort(a,a+10,cmp);
	int x;


	
	while (scanf("%d", &x) != EOF)
	{
		
		for (int i = 0; i<10; i++)
			printf("%d ", i);
		printf("\n");
		for (int i = 0; i<10; i++)
			printf("%d ", a[i]);
		printf("\n");
		int flag = 1;
		int less_last_mid = -1;
		int low = 0, high = 9, mid;

		while (low <= high)//循环必须包括等于,因为只有包括等于,才会把low,high数据都访问一遍。
		{
		
				//在查找指定目标值时,可能漏掉
				//例如,倒数第二步时,low, high=low+1;mid取floor((low+high)/2)=low,只把low访问到了,可能漏掉high没有访问到,下次就是(mid偏小,漏掉)<br>                //low=mid+1或者(mid偏大)high=mid-1(high<low);即

				//high<-mid->low
				//low  high
				//如果只是查找目标值,只需要比较等于即可。

				//如果要查找到大于等于目标值的最小值,应该就是high的最后位置,因为high一开始就是大于等于目标值,直到high向左移动的最后的位置,如果high最终的位置比目标值还要小,
				//则查找不到。

				//同样地,如果查找小于等于目标值的最大值,应该就是low的最后位置,如果low的最终位置比目标值还要大,则查找不到。<br>
				//如果要找到小于x的最大值,则
				//最后一步,flag=0时,flag=1时的最后一次mid,即less_last_mid为x最终的值
				//如果flag = 1时, 保存最后一次mid即可,即data[less_last_mid]
			    //另外就是越界,找不到
			mid = (low + high) / 2;
			if (a[mid] < x)//如果1:要找的是小x的最大值;

			{//如果2:要找的是小于等于x的最大值; if (a[mid] <= x)

				less_last_mid = mid;
				low = mid + 1;
				flag = 1;//假设最后一步,走在这里,变成了low>high这个无理的条件,这是因为Low的变化造成的,所以low的值已无法使用
			}

			else
			{
				high = mid - 1;
				flag = 0;//假设最后一步,走在这里,变成了low>high这个无理的条件,这是因为high的变化造成的,所以high的值已无法使用
			}
		}
		if (flag)
		{//肯定存在
			printf("flag=0:%d\n", a[less_last_mid]);
		}
		else//可能不存在,调整high左移
		{
			if (high >= 0)
			{
				printf("flag=0:%d\n", a[less_last_mid]);
			}
			else
			{
				printf("不存在\n");
			}
		}
	}

  

posted @ 2018-11-19 17:03  WELEN  阅读(1112)  评论(0)    收藏  举报