[数组][查表][折半查找]-Java第4天课程

[数组]折半查找原理:

折半顾名思义就是中间,即取该数组中的中间的那个值arr[mid],与需要查找的key数作判断,先判断是否等于,否则判断key>arr[mid]或者key<arr[mid],大于则最小值需要重新指向原中间值后一个元素,小于则最大值需要重新指向中间值前一个元素,即判断大于则最小值往右边移,判断小于则最大值往左边移,然后继续取间值进行判断是否等于...否则继续判断key>arr[mid]或者key<arr[mid],直到找到符合的值,或没找到符合的值,返回结果

写代码时发生过的错误:

1.数组必须为有序的数组

2.无法查找对应值的时候,继续折半的话,并不只是min或者max重新指向了,还必须重新计算mid的值

3.循环体用错

4.min>max理解错误,误以为必须单纯的一直往最左或最右移动,没考虑到运行时,min和max都是有机会变化的,所以min>max很正常。

示例:

以下有一组数 int [9] arr ={2,4,7,15,25,37,56,85,152,477};

需要查找的是152

min初始化为0

max初始化为arr.length-1 (这里要拿的是数组角标值,数组从arr[0]开始,所以需要元素个数减去1)

mid=(max+min)/2

所以首先取中间值是 mid = arr[4]=25,这里只取中间的整数即9/2=4

判断 25是不是要找的数?不是

判断 152>25? 是

继续折半处理

此时

min=mid+1=arr[5]

max不变=arr[9]

mid=arr[7]=45

判断 45是不是要找的数?不是

判断 152>45? 是

第三次折半处理

此时

min=mid+1=arr[8]

max不变=arr[9]

mid=arr[8]=152

判断 152是不是要找的数?是

则返回该值

如果折中完所有元素都不符合的话,就要返回一个空值-1(即没有),需要一个判断条件,min>max,意思当最小值都大于最大值的时候,不可能再折半了(已理解注:min>max这个条件思维上不是太明白,数组里如果取到最值的情况下,应该min=max,不知什么情况下会出现min>max,方法2中的 while(min<=max)同理,但方法2还是较好理解,只要min<=max,肯定能折半

min>max 理解模型:当数组中没有符合的元素的情况下 要一个判断来返回-1(即没有),所以取一个不存在数组里的数 比如 148

数组 {2,4,7,15,25,37,56,85,152,477} 

min=0,max=9,mid=4=25,148>25?是,继续

min=4+1=5,max=9,mid=(5+9)/2=7=85,148>25?是继续

min=7+1=8,max=9,mid=(7+9)/2=8=152,148<152,max值左移,min不变

min=8,max=8-1=7,此时min>max

--------------以下为源代码-------------------------------------------------------------------- 

/*
数组的查找操作-折半查找-方法1
*/
class  ArrayTest4
{
	public static void main(String[] args) 
	{
		int[]arr={2,4,7,15,25,37,56,45,152,477};
		int index=halfSearch(arr,4770);
		System.out.println("index="+index);
	}
	//折半查找-方法1-以判断找不找得到符合的值为条件进行折半查找,当找到之后直接返回该值,找不到则继续循环体折半直到无法折半查找
	public static int halfSearch(int []arr,int key)
	{	/*定义三个变量,最大值,最小值,中间值,初始化中间值即为最大值与最小值的和的一半*/
		 int min,max,mid;
		 max=arr.length-1;//这里要拿的是数组角标值,数组从arr[0]开始,所以需要元素个数减去1
		 min=0;
		 mid=(max+min)/2;
		 //循环体,直到找到符合条件的数结束循环并返回mid
		 while (arr[mid]!=key)
		 {	
			if (key>arr[mid])
				min=mid+1;//继续折半,因为判断大于,需要右移,则min需要重新指向中间值之后的一个元素,max不变
			else if(key<arr[mid])
				max=mid-1;//继续折半,因为判断小于,需要左移移,则max需要重新指向中间值之前的一个元素,min不变
			if(min>max)	//当找不到符合值的判断条件
			return -1;
			mid=(max+min)/2;  //继续取中间值
		 }
		 return mid;
	}
}

-------------------------------------有木有见过这么可爱的分割线^_^-------------------------------------------------

/*
数组的查找操作-折半查找-方法2
*/
class  ArrayTest4
{
	public static void main(String[] args) 
	{
		int[]arr={2,4,7,15,25,37,56,45,152,477};
		int index=halfSearch_2(arr,4770);
		System.out.println("index="+index);
	}
//折半查找-方法2-以判断最小值和最大值为条件,min不论小于还是等于max,就存在中间值
	public static int halfSearch_2(int []arr,int key)
	{
		 int min,max,mid;
		 max=arr.length-1;
		 min=0;

		 while (min<=max)//只要这个条件成立,肯定能折半
		 {
			mid=(max+min)/2;//循环体内取中间值
			if (key>arr[mid])
				min=mid+1;
			else if(key<arr[mid])
				max=mid-1;	
			else 
				return mid;//即不大于也不小于,那就只能是等于,也就是找到这个值了,返回即可
		 }
		 return -1;//当条件min<=max不成立的时候,返回-1
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,可以使用数组查表法来查找0-16383之间的数。首先,我们可以创建一个包含16384个元素的数组,每个元素对应一个数。然后,我们可以将每个元素的值设置为对应的数。例如,数组的第一个元素的值为0,第二个元素的值为1,以此类推,直到最后一个元素的值为16383。接下来,我们可以通过输入一个数来查找它在数组中的位置。如果找到了该数,我们可以输出它在数组中的索引值,即对应的位置。如果没有找到该数,我们可以输出"not found"。以下是一个示例代码: ```c #include <stdio.h> int main() { int table\[16384\]; int target; // 创建查找表 for (int i = 0; i < 16384; i++) { table\[i\] = i; } // 输入要查找的数 printf("请输入要查找的数:"); scanf("%d", &target); // 在查找表中查找数的位置 int found = 0; for (int i = 0; i < 16384; i++) { if (table\[i\] == target) { printf("数 %d 的位置为 %d\n", target, i); found = 1; break; } } if (!found) { printf("未找到该数\n"); } return 0; } ``` 在上述代码中,我们首先创建了一个包含16384个元素的数组`table`,并将每个元素的值设置为对应的数。然后,我们通过输入一个数来查找它在数组中的位置。如果找到了该数,我们输出它在数组中的索引值;如果没有找到该数,我们输出"未找到该数"。 #### 引用[.reference_title] - *1* [C语言数组查找](https://blog.csdn.net/m0_43450897/article/details/88827094)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C语言 二维数组查找 二分查找折半查找)、暴力搜索(暴力求解)、线性查找(从右上角出发查找、从左下...](https://blog.csdn.net/undefinedUser_1/article/details/121984410)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [1242_C语言实现简单的查表](https://blog.csdn.net/grey_csdn/article/details/124851232)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值