查找有序数组中的具体数字n
方法一:逐个比较法
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sz = sizeof(arr) / sizeof(arr[0]);//siaeof(arr)计算出的是整个数组所占的字节大小,即10*4=40,sizeof(arr[0])计算出的是数组中第一个元素所占字节的大小,即为4,所以用所有元素所占字节的大小除以一个元素所占字节的大小即为数组中元素的个数。
int i = 0;
int k = 7;
for (i = 0; i < sz; i++)
{
if (arr[i] == k)
{
printf("找到了,下标是%d\n", i);
break;//一定注意找到元素后要跳出循环
}
}//利用for语句将数组中的每一个元素与k相比较
if (i >= sz)//若没有找到需要说明,则需要注意循环语句的判断条件和变量的调整
{
printf("没有找到!\n");
}
return 0;
}
总结:
1.对于计算数组中元素的数量,即sizeof(arr)/sizeof(arr[0]),用整个数组所占字节的大小除以数组中一个元素所占字节的大小,所得结果即元素个数
2.循环外的语句一定要注意循环中的判断条件和变量调整
3.在循环语句中,若是完成循环体后不再需要进行循环,利用break或者continue语句跳出循环
方法二:折半查找法
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int k = 0;
scanf("%d", &k);
int left = 0;
int sz = 0;
sz = sizeof(arr) / sizeof(arr[0]);
int right = sz - 1;//数组最大下标即:元素数量-1
int mid = 0;
while (left <= right)//因为在不断缩小范围,所以left和right在一直靠拢,当left=right时,mid指向的是同一个元素
{
mid = (left + right) / 2;//因为每次都要重置查找范围,所以每次定范围时要重新定义mid
if (k > arr[mid])
{
left = mid + 1;
}
else if (k < arr[mid])
{
right = mid - 1;
}
else
{
printf("找到了,下标为%d", mid);
break;//在查找数字中若找到后一定要用相应语句跳出循环,否则会陷入死循环
}
}
if (left>right)
{
printf("没有找到");
}
return 0;
}
总结:
1.找出数字的中间元素
2.中间元素与输入数字比较,确定新的查找范围
3.数组下标最大即数组元素-1
4.在循环体中完成任务之后务必用break或者continue跳出循环,否则会陷入死循环
5.在计算中间元素的坐标时,若是括号内的两个数字都比较大,那么两个数字加起来就有可能超过整形的最大限度,导致二进制的一些数据丢失,因此可以使用以下思路:
在计算A和B的平均值时可以先计算出B比A多出的部分,除以2以后两者平均即可
所以计算mid的式子可以表示为:
mid=left+(right-left)/2