#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>
...