折半查找法.docx

上传人:b****7 文档编号:26648646 上传时间:2023-06-21 格式:DOCX 页数:13 大小:652.61KB
下载 相关 举报
折半查找法.docx_第1页
第1页 / 共13页
折半查找法.docx_第2页
第2页 / 共13页
折半查找法.docx_第3页
第3页 / 共13页
折半查找法.docx_第4页
第4页 / 共13页
折半查找法.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

折半查找法.docx

《折半查找法.docx》由会员分享,可在线阅读,更多相关《折半查找法.docx(13页珍藏版)》请在冰豆网上搜索。

折半查找法.docx

折半查找法

二分查找是在我们整个数据结构当中一个比较重要的算法,它的思想在我们的实际开发过程当中应用得非常广泛。

在实际应用中,有些数据序列是已经经过排序的,或者可以将数据进行排序,排序后的数据我们可以通过某种高效的查找方式来进行查找,今天要讲的就是折半查找法(二分查找),

它的时间复杂度为O(logn),将以下几个方面进行概述

了解二分查找的原理与思想

分析二分查找的时间复杂度

掌握二分查找的实现方法

了解二分查找的使用条件和场景

1二分查找的原理与思想

在上一个章节当中,我们学习了各种各样的排序的算法,接下来我们就讲解一下针对有序集合的查找的算法—二分查找(BinarySearch、折半查找)算法,二分查找呢,是一种非常容易懂的查找算法,它的思想在我们的生活中随处可见,

比如说:

同学聚会的时候喜欢玩一个游戏——猜数字游戏,比如在1-100以内的数字,让别人来猜从,猜的过程当中会被提示是猜大了还是猜小了,直到猜中为止。

这个过程其实就是二分查找的思想的体现,这是个生活中的例子,在我们现实开发过程当中也有很多应用到二分查找思想的场景。

比如说仙现在有10个订单,它的金额分别是6、12、15、19、24、26、29、35、46、67请从中找出订单金额为15的订单,利用二分查找的思想,那我们每一次都会与中间的数据进行比较来缩小我们查找的范围,下面这幅图代表了查找的过程,其中low,high代表了待查找的区间的下标范围,mid表示待查找区间中间元素的下标(如果范围区间是偶数个导致中间的数有两个就选择较小的那个)

第一次二分查找

第二次二分查找

第三次二分查找

通过这个查找过程我们可以对二分查找的思想做一个汇总:

二分查找针对的是一个有序的数据集合,查找思想有点类似于分治思想。

每次都通过跟区间的中间元素对比,将待查找的区间范围缩小为原来的一半,直到找到要查找的元素,或者区间被缩小为0。

一:

查找的数据有序

二:

每次查找,数据的范围都在缩小,直到找到或找不到为止。

2二分查找的时间复杂度

我们假设数据大小为n,每次查询完之后,数据就缩减为原来的一半,直到最后的数据大小被缩减为1

n,n/2,n/4,n/8,n/16,n/32,…………,1

这是一个等比数列,当数据大小变为1时,

k是总共缩小的次数,而每次缩小只涉及两个数据的比较大小,所以经过了K次区间缩小操作,通过计算k的值我们就可以得出二分查找的时间复杂度是O(logn)

这是一种非常高效的时间复杂度,有时候甚至比O

(1)复杂度更高效,为什么这么说呢?

因为对于logn来说即使n的非常大,对应的logn的值也会很小,之前在学习O

(1)时间复杂度时我们说过O

(1)代表的是一种常量级的时间复杂度,并不是说代码只需要执行一条语句,有时候可能要执行100次,1000次,这样常规级次数都用O

(1)来表示,所以,常量级时间复杂度的算法有时候还没有O(logn)的算法执行效率高。

 

3二分查找算法的实现

I有序数列当中不存在重复的元素

#include

usingnamespacestd;

/*

但是若low+high>Interger.MAX_VALUE时,此时会导致数据溢出,则导致mid错误,

所以mid应该改为low+(high-low)/2;

*/

//递归二分查找//

intbinaS(int*arr,intkey,inthigh,intlow)

{

if(low>high)

return-1;

intmid=(high+low)/2;

if(arr[mid]==key)

{

returnmid;

}

elseif(arr[mid]>key)

{

binaS(arr,key,low,mid-1);

}

else

{

binaS(arr,key,mid+1,high);

}

}

intmain()

{

//二分查找

inta[4]={11,22,33,44};

intkey;

cin>>key;

cout<

//intlow=0,high=3,flag=1,mid;

//while(low<=high)

//{

//mid=(low+high)/2;

//if(key==a[mid])

//{

//cout<

//

////flag=0;

////break;

//}

//elseif(key

//{

//high=mid-1;

//}

//elseif(key>a[mid])

//{

//low=low+1;

//}

//}

//if(flag)

//cout<<"没有找到";

return0;

}

II有序数列当中存在重复的元素

思路1:

#include

usingnamespacestd;

//数据序列中第一个等于给定的元素(重复元素)

intbinarySearch(int*array,intvalue,intlength)

{

intlow=0;

inthigh=length-1;

while(low<=high)

{

intmid=low+(high-low)/2;

if(array[mid]==value)

{

//当我们的mid指针已经指向第一个元素或者我们的mid指针前一个元素不等于我们的查找

//元素的时候,直接返回mid下标

if(mid==0||array[mid-1]!

=value)

{

returnmid;

}//否则,继续二分查找

else

{

high=mid-1;

}

}

elseif(array[mid]

{

low=mid+1;

}

elseif(array[mid]>value)

{

high=mid-1;

}

}

return-1;

}

intmain()

{

intarray[]={6,12,15,19,24,26,29,29,29,67};

cout<

return0;

}

思路2:

#include

usingnamespacestd;

/*

需求2:

从数据序列中查找最后一个值等于给定值的元素

*/

intbinarySearch(int*arr,intvalue,intlen)

{

intlow=0,high=len-1;

while(low<=high)

{

intmid=low+(high-low)/2;

if(arr[mid]==value)

{

//和查找第一个元素的思路是一样的

if(mid==len-1||arr[mid+1]!

=value)

returnmid;

//否则继续查找,往后查找

else

{

low=mid+1;

}

}

elseif(arr[mid]>value)

{

high=mid-1;

}

elseif(arr[mid]

{

low=mid+1;

}

}

return-1;

}

intmain()

{

intarray[]={6,12,15,19,24,26,29,29,29,67};

cout<

return0;

}

#include

usingnamespacestd;

/*

从数据序列中查找第一个大于等于给定值的元素

 

while(low<=high)

{

intmid=low+(high-low)/2;

if(arr[mid]>=value)

{

if(mid==0||arr[mid-1]

returnmid;

else

high=mid-1;

}

elseif(arr[mid]

{

low=mid+1;

}

}

return-1;

*/

intbinarySearch(int*arr,intvalue,intlen)

{

intlow=0,high=len-1,max=-1;

while(low<=high)

{

intmid=low+(high-low)/2;

if(arr[mid]==value)

{

if(mid==0||arr[mid-1]!

=value)

{

returnmid;

}

else

{

high=mid-1;

}

}

elseif(arr[mid]>value)

{

max=mid;

high=mid-1;

}

elseif(arr[mid]

{

low=mid+1;

}

}

returnmax;

}

intmain()

{

intarray[]={6,12,15,19,24,26,29,29,29,67};//{1,3,5,7,9};

cout<

return0;

}

 

#include

usingnamespacestd;

/*

从数据序列当中查找出最后一个小于等于给定值的元素

*/

intbinarySearch(int*arr,intvalue,intlen)

{

intlow=0,higg=len-1;

while(low<=high)

{

intmid=low+(high-low)>>1;

if(arr[mid]<=value)//1122

{

if(mid==len-1||arr[mid+1]>value)

returnmid;

else

low=mid+1;

}

else

{

high=mid-1;

}

}

return-1;

}

 

intmain()

{

return0;

}

二分查找法的使用条件和场景

 

拓展:

log2NO(logN)logaN=logcN/logca,因1/logca不是1,所以舍去,剩下logcN,c可以是任何的值,不关心,所以是logN

 

案例一:

跳房子(这…,看题我都要看半小时)

每年,奶牛都会举办一场特殊版本的跳房子活动,其中包括小心翼翼地从河中的一块石头跳到另一块石头。

这个令人兴奋的活动发生在一条又长又直的河流上,一块石头开始,另一块石头结束。

从开始走的长度L(1<=L<=1,000,000,000)。

从开始到结束之间的石头数量为N(0<=N<=50000),从开始每块石头有一个整数距离di(0

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学案例设计

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1