二分查找及利用函数二分查找
当朋友买了一双新鞋子并说这双鞋不到600块钱,让你猜猜它的价格是多少,你会怎么猜?
一块,两块,三块······还是先说三百块,根据他给出的提示再继续折半/二分查找。显然是后者,因为它的效率较高,由此当给予一个升序排列的数组时,要代码实现查找某个元素是否在该数组中用二分查找法。
为了复习一下,我还是把普通的遍历一遍先打出来。
#include<stdio.h>int main(){int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int i = 0, k = 0;int sz=sizeof(arr)/sizeof(arr[0]);//sizeof(arr)所测得的是整个数组的大小printf("请输入要查找的元素:");scanf("%d", &k);for (i = 0; i < sz; i++){if (arr[i] == k){printf("找到了,其下标为%d\n", i);break;}}if (i == 10){printf("没有该元素\n");}return 0;}
#include<stdio.h>int main(){int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int i = 0, k = 0;int sz = sizeof(arr) / sizeof(arr[0]);//sizeof(arr)所测得的是整个数组的大小int left = 0;int right = sz - 1;//先设定左右起始下标printf("请输入要查找的元素:");scanf("%d", &k);while (left <= right)//只要左比右小,就一直查找{int mid = left+(right-left)/2;//mid要时时刷新,所以定义在while里面//(left + right) / 2,可能会出现溢出现象,不宜使用//left/2+right/2存在后边的情况,不宜使用(如(3+5)/2=4,3/2+5/2=3)if (arr[mid] > k){ right = mid - 1;}else if (arr[mid] < k){ left = mid + 1;}else{printf("找到了,下标为%d", mid);break;}}if (left>right){printf("找不到该元素\n");}return 0;}
接下来就是函数形式的二分查找了
#include<stdio.h>int reacher(int arr[],int k,int sz){int left = 0;int right = sz - 1;while (left <= right){int mid = left + (right - left) / 2; if (arr[mid] > k){ right = mid - 1;}else if (arr[mid] < k){ left = mid + 1;}else{return mid;}}return -1;//无需判断left和right的关系,到这里只能是查无此元素} int main(){int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int i = 0, k = 0;int sz = sizeof(arr) / sizeof(arr[0]);//sizeof(arr)所测得的是整个数组的大小printf("请输入要查找的元素:");scanf("%d", &k);int ret=reacher(arr, k, sz);//sz需要在主函数算好后传过去if (ret == -1) //否则,在函数中sizeof(arr)的值是首位元素的大小,无法求解sz{printf("找不到该元素\n");}else{printf("找到了,其下标为%d",ret);}return 0;}
ps:望各位大佬可以指出我的不足