詳解Go語(yǔ)言實(shí)現(xiàn)線性查找算法和二分查找算法
線性查找
線性查找又稱順序查找,它是查找算法中最簡(jiǎn)單的一種。它的基本思想是在在一組數(shù)據(jù)中,從第一個(gè)元素開始,依次和預(yù)期值比較,直到和預(yù)期值相等,則查找成功,如果所有元素都比較過(guò),沒(méi)找到與預(yù)期值相等的元素,則查找失敗。
算法
func LinearSearch(nums []int, target int) int { for i, num := range nums { if num == target { return i } } return -1 }
算法很簡(jiǎn)單,遍歷 nums
切片,然后依次比較,找到與 target
相等的元素則返回該元素在切片中的下標(biāo)值,否則返回 -1
,表示沒(méi)有找到與 target
相等的元素。
該算法的時(shí)間復(fù)雜度為 O(N)??梢园l(fā)現(xiàn),如果切片里有很多元素,然后要查找到元素處于最后一個(gè)位置,或者根本就沒(méi)有要查找的元素,算法將遍歷一整個(gè)切片,這種查找效率很低。
二分查找
二分查找,也稱折半查找,相比于線性查找,它是一種效率較高的算法,但是二分查找要求數(shù)組或切片中的元素必須是有序存儲(chǔ)的。時(shí)間復(fù)雜度為 O(logn)。圖解:
nums
= [1, 2, 3, 4, 5]
- 劃定左邊界
left
和右邊界right
,初始值分別為 0 ,數(shù)組長(zhǎng)度 - 1 = 5 - 1 = 4 - 遍歷數(shù)組
nums
,取區(qū)間的中間位置mid
=left
+(right - left)
/ 2 = 2,使用這個(gè)公式而不是 [(left + right)
/ 2] 是防止left + right
之后的值溢出。 - 比較數(shù)值,如果中間值
nums[mid]
與 目標(biāo)值target
相等,則結(jié)束查找 - 如果中間值
nums[mid]
大于目標(biāo)值target
,說(shuō)明要尋找的值可能在左邊的區(qū)間,移動(dòng)右邊界的位置,往坐區(qū)間尋找。 - 如果中間值
nums[mid]
小于目標(biāo)值target
,說(shuō)明要尋找的值可能在右邊的區(qū)間,移動(dòng)左邊界的位置,往坐區(qū)間尋找。 - 重復(fù)以上查找的操作,直到找到元素,或遍歷結(jié)束。
算法
func BinarySearch(nums []int, target int) int { left, right := 0, len(nums)-1 for left <= right { mid := left + (right-left)/2 if nums[mid] == target { return mid } else if nums[mid] > target { right = mid - 1 } else { left = mid + 1 } } return -1 }
上述代碼是基于區(qū)間【左閉右閉】的特點(diǎn)去編寫的,左閉右閉就是區(qū)間涵蓋左邊界的元素和右邊界的元素。
【左閉右閉】這個(gè)特點(diǎn)會(huì)影響 for
循環(huán) 的條件 → left <= right
,因?yàn)閰^(qū)間包含右元素,因此left
等于 right
是有意義的。
除此之外,左閉右閉的特點(diǎn)還會(huì)影響 left
和 right
的值,初始值為 0,和 len
- 1。因?yàn)?mid
的值已經(jīng)比較過(guò)了,基于左閉右閉的特點(diǎn),left
下次的值應(yīng)為 mid + 1
,而 right
下次的值應(yīng)為 mid - 1
,不能為 mid
。
總之,左閉右閉的特點(diǎn),影響著循環(huán)條件,和 left
與 right
的值。
- 初始值
left = 0
,right = len - 1
- 循環(huán)條件
left <= right
- 后續(xù)值
left = mid + 1
,right = mid -1
【左閉右開】的算法:
func BinarySearch(nums []int, target int) int { left, right := 0, len(nums) for left < right { mid := left + (right-left)/2 if nums[mid] == target { return mid } else if nums[mid] > target { right = mid } else { left = mid + 1 } } return -1 }
左開右閉,涵蓋左邊的元素,不包含右邊的元素,因此 left
= 0,我們要取到數(shù)組的最后一個(gè)元素,right
的值取不到,因此 right
= len
,這樣就能取到 len - 1
的值了。
循環(huán)條件,left
< right
,沒(méi)有等于號(hào),因?yàn)?right
取不到,等于的話是沒(méi)有意義的。
由于 mid
已經(jīng)比較過(guò)了,后續(xù) left
的值為 mid + 1
,right
的值為 mid
。
總結(jié)
- 初始值
left = 0
,right = len
- 循環(huán)條件
left < right
- 后續(xù)值
left = mid + 1
,right = mid
小結(jié)
本文對(duì)線性查找算法和二分查找算法進(jìn)行了介紹。線性查找算法雖簡(jiǎn)單,但是查找效率低,時(shí)間復(fù)雜度為 O(N);而二分查找法效率雖較高,但是所查找的數(shù)組必須是有序的,時(shí)間復(fù)雜度為 O(logn),基于區(qū)間特點(diǎn)的不同(左閉右閉、左閉右開),二分查找算法的寫法也不同。
到此這篇關(guān)于詳解Go語(yǔ)言實(shí)現(xiàn)線性查找算法和二分查找算法的文章就介紹到這了,更多相關(guān)Go查找算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang gin 框架 異步同步 goroutine 并發(fā)操作
這篇文章主要介紹了golang gin 框架 異步同步 goroutine 并發(fā)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12Golang基礎(chǔ)學(xué)習(xí)之map的示例詳解
哈希表是常見的數(shù)據(jù)結(jié)構(gòu),有的語(yǔ)言會(huì)將哈希稱作字典或者映射,在Go中,哈希就是常見的數(shù)據(jù)類型map,本文就來(lái)聊聊Golang中map的相關(guān)知識(shí)吧2023-03-03Golang中的select語(yǔ)句及其應(yīng)用實(shí)例
本文將介紹Golang中的select語(yǔ)句的使用方法和作用,并通過(guò)代碼示例展示其在并發(fā)編程中的實(shí)際應(yīng)用,此外,還提供了一些與select相關(guān)的面試題,幫助讀者更好地理解和應(yīng)用select語(yǔ)句2023-12-12詳解Go語(yǔ)言中Goroutine退出機(jī)制的原理及使用
goroutine是Go語(yǔ)言提供的語(yǔ)言級(jí)別的輕量級(jí)線程,在我們需要使用并發(fā)時(shí),我們只需要通過(guò)?go?關(guān)鍵字來(lái)開啟?goroutine?即可。本文就來(lái)詳細(xì)講講Goroutine退出機(jī)制的原理及使用,感興趣的可以了解一下2022-07-07golang簡(jiǎn)單獲取上傳文件大小的實(shí)現(xiàn)代碼
這篇文章主要介紹了golang簡(jiǎn)單獲取上傳文件大小的方法,涉及Go語(yǔ)言文件傳輸及文件屬性操作的相關(guān)技巧,需要的朋友可以參考下2016-07-07在Linux系統(tǒng)中安裝Go語(yǔ)言的詳細(xì)教程
這篇文章主要介紹了在Linux系統(tǒng)中安裝Go語(yǔ)言的詳細(xì)教程,由于國(guó)內(nèi)很多人對(duì)谷歌的盲目追捧,導(dǎo)致Go語(yǔ)言在國(guó)內(nèi)的人氣遠(yuǎn)超國(guó)外...需要的朋友可以參考下2015-06-06