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

本文深入探讨了折半查找算法的核心原理,通过实例展示了如何在有序数组中高效定位目标值。详细阐述了算法步骤,包括初始化、判断条件、循环体结构以及退出条件,同时提供了两种不同实现方式的源代码,帮助读者更好地理解和实践折半查找技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[数组]折半查找原理:

折半顾名思义就是中间,即取该数组中的中间的那个值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
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值