带---有测试代码----的二分法查找(折半查找)

#include <stdio.h>
#include <assert.h>

/*
 * 带有测试代码的二分法查找
 * Precondition:已经排好序
 * Maintenance:如果find_this 在数组中的话 就一定能找得出来
 * Postcondition:如果find_this 不在数组中的话,就一定要保证能返回-1
 * */

#define len 8
int arr[] = {1,2,2,2,5,6,8,9};

int is_sort(void)
{
	int i;
	for(i = 0; i < len; i++)
		if(arr[i - 1] > arr[i])
			return 0;//非排好序,返回错误
	return 1;//排好序的
}

int mustbe(int start,int end,int find_this)
{
	int i;
	for(i = 0; i < start; i++)
		if(arr[i] == find_this)
			return 0;//返回错误
	for(i = end + 1; i < len; i++)
		if(arr[i] == find_this)
			return 0;//返回错误
	return 1;//正确
}

int contains(int n)
{
	int i;
	for(i = 0; i < len; i++)
		if(n == arr[i])
			return 1;//确保要找的数在数组中
	return 0;//要找的数不在数组中
}

int binary_search(int find_this)
{
	int mid,start = 0,end = len;

	/*
	 * Precondition
	 * */	
	assert(is_sort());//保证数组是已经排好序的

	while(start <= end)
	{
		mid = (start + end) / 2;

		/*
		 * Maintenance
		 * */
		assert(mustbe(start,end,find_this));

		/*
		 * 要找的数位于右半部分
		 * 结束边界不变,还是end
		 * 开始边界是之中间边界加1,所以是mid + 1
		 * */
		if(arr[mid] < find_this)
			start = mid + 1;

		/*
		 * 要找的数位于左半部分
		 * 起始边界不变,结束边界是之前的中间边界减1所以是mid - 1
		 * */
		else if(arr[mid] > find_this)
			end = mid - 1;

		/*
		 * 这个就是要找的数
		 * */
		else
		{
			/*
			 * Postcondition1
			 * */
			assert(mid >= start && mid <= end && arr[mid] == find_this);
			return mid;
		}
	}

	/*
	 * 没有要找的数,返回失败
	 * Postcondition2
	 * */
	assert(!contains(find_this));
	return -1;
}

int main()
{
	int i;
	for(i = 0; i < len; i++)
		printf("%d ",arr[i]);
	printf("\n");
	int find;
	printf("What you wanna find:");
	scanf("%d",&find);
	int res = binary_search(find);
	printf("pos = %d,brr[%d] = %d\n",res,res,arr[res]);

}


测试代码只是由于开发调试用,软件正式版发布时可以用  -DNDEBUG 来屏蔽运行测试代码

如:gcc -DNDEBUG xx.c  这样的方式就可以禁用assert.h中的assert宏定义,这样代码中的所有assert测试都不起作用了。

 

或者是在头上添加"#define NDEBUG"

#define NDEBUG
#include <stdio.h>
#include <assert.h>
...

 

 

你可能感兴趣的:(带---有测试代码----的二分法查找(折半查找))