網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
c++與python實(shí)現(xiàn)二分查找的原理及實(shí)現(xiàn)_C 語(yǔ)言
作者:機(jī)器學(xué)習(xí)入坑者 ? 更新時(shí)間: 2022-05-14 編程語(yǔ)言在計(jì)算機(jī)中,數(shù)據(jù)的查找方式與其存儲(chǔ)方式關(guān)系密切。試想一下,如果圖書館中書籍雜亂無(wú)章的存放,那么要想找到心儀的書籍將會(huì)非常困難。為此,人們常常將物品按照某種規(guī)則或次序進(jìn)行放置,目的是便于日后的查找。
作為查找算法家族中的一員,二分查找正是利用數(shù)據(jù)按次序存儲(chǔ)這一優(yōu)點(diǎn),極大的提升了查找目標(biāo)值所在位置的速度。
二分查找的核心思想是:首先將數(shù)組中間值和目標(biāo)值進(jìn)行比較,如果相等則返回;如果不相等,則選擇中間值左邊的一半或者右邊的一半進(jìn)行比較;不斷重復(fù)直到檢索完畢。首先來(lái)看下面這個(gè)gif,其中藍(lán)色圈表示左位置,粉色圈表示右位置,綠色圈表示中間位置:
首先定義的是左邊界(藍(lán)色圈)和右邊界(粉色圈),進(jìn)而根據(jù)左邊界和右邊界計(jì)算出中間位置(綠色圈);然后,比較中間位置的值和目標(biāo)值的大小,比較結(jié)果包含3種情況
- 如果相等則表示查找成功,返回中間位置;
- 如果中間位置的值小于目標(biāo)值,則說(shuō)明目標(biāo)值在中間位置到右邊界這一半;
- 如果中間位置的值大于目標(biāo)值,則說(shuō)明目標(biāo)值在左邊界到中間位置這一半;
上述步驟的循環(huán)需要終止條件,即左邊界小于或等于右邊界,表明此時(shí)已經(jīng)搜索完成,目標(biāo)數(shù)值不在數(shù)據(jù)中存在。
1、時(shí)間復(fù)雜度與優(yōu)缺點(diǎn)
既然每次搜索后區(qū)間長(zhǎng)度都減半,假設(shè)數(shù)據(jù)個(gè)數(shù)(即區(qū)間長(zhǎng)度)為n,那么算法每次迭代得到的區(qū)間長(zhǎng)度依次為n/2,n/4,n/8等等,其通項(xiàng)如下,k表示循環(huán)次數(shù):
最壞的情況,就是搜索到區(qū)間長(zhǎng)度為1,即最后只剩1個(gè)元素:
?
所以,可以求得最壞情況下需要運(yùn)行的次數(shù)為:
因此二分查找復(fù)雜度為O(logn),相比于順序查找其速度獲得了極大的提高(優(yōu)點(diǎn))。但是,必須注意二分查找需要保證數(shù)據(jù)是有序的,這就要求數(shù)據(jù)必須預(yù)先進(jìn)行排序(缺點(diǎn))。
2、python實(shí)現(xiàn)
def binary_search(ordered_list, target_value): ? ? """ ? ? Args: ? ? ? ? ordered_list: data with order ? ? ? ? target_value: value that want be searched ? ? """ ? ? left = 0 ? ? right = len(ordered_list)-1 ? ? # 終止條件 ? ? while left <= right: ? ? ? ? # 中間位置計(jì)算 ? ? ? ? mid = int((left+right)/2) ? ? ? ? if ordered_list[mid] == target_value: ? ? ? ? ? ? return "index is {}, target value is {}".format(mid, ordered_list[mid]) ? ? ? ? # 此時(shí)目標(biāo)值在中間值右邊,更新左位置 ? ? ? ? elif ordered_list[mid] < target_value: ? ? ? ? ? ? left = mid + 1 ? ? ? ? # 此時(shí)目標(biāo)值在中間值左邊,更新右位置 ? ? ? ? elif ordered_list[mid] > target_value: ? ? ? ? ? ? right = mid - 1 ? ? # 搜索結(jié)束沒(méi)有找到 ? ? return "Not find"
3、C++實(shí)現(xiàn)
int binarySearch(int *orderedData, int dataLength, int targetValue) { ?? ?int left = 0; ?? ?int right = dataLength - 1; ?? ?int mid; ?? ?// 終止條件 ?? ?while (left<=right) ?? ?{ ?? ??? ?// 中間位置計(jì)算 ?? ??? ?mid = (left + right) / 2; ?? ??? ?if (*(orderedData + mid) == targetValue) { ?? ??? ??? ?return mid; ?? ??? ?} ?? ??? ?// 目標(biāo)值在中間值右邊,更新左位置 ?? ??? ?else if (*(orderedData + mid) < targetValue){ ?? ??? ??? ?left = mid + 1; ?? ??? ?} ?? ??? ?// 目標(biāo)值在中間值左邊,更新右位置 ?? ??? ?else ?? ??? ?{ ?? ??? ??? ?right = mid - 1; ?? ??? ?} ?? ?} ?? ?// 搜索不到,返回-1 ?? ?return -1; }
原文鏈接:https://zhuanlan.zhihu.com/p/105906443
相關(guān)推薦
- 2022-05-25 spring的構(gòu)造函數(shù)注入屬性@ConstructorBinding
- 2022-05-06 如何利用Python處理excel表格中的數(shù)據(jù)_python
- 2022-05-22 Nginx設(shè)置HTTPS的方法步驟_nginx
- 2022-09-18 K8s實(shí)戰(zhàn)教程之容器和?Pods資源分配問(wèn)題_云其它
- 2022-05-05 詳解C語(yǔ)言結(jié)構(gòu)體中的char數(shù)組如何賦值_C 語(yǔ)言
- 2022-09-15 C++中的整形字節(jié)數(shù)_C 語(yǔ)言
- 2022-06-28 ES6基礎(chǔ)語(yǔ)法之Map和Set對(duì)象_基礎(chǔ)知識(shí)
- 2022-10-08 Qt動(dòng)態(tài)庫(kù)調(diào)用宿主進(jìn)程中的對(duì)象方法純虛函數(shù)使用_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支