小朋友們好,大朋友們好!
我是貓妹,一名愛上Python程式設計的國小生。
歡迎和貓妹一起,趣味學Python。
今日主題
貓妹最近不是在學習《人工智能程式設計實踐Python5級》嗎?
這裡面除了基本的Python知識外,還有幾章是介紹算法的。
算法,對貓妹來說是陌生的,畢竟剛接觸嘛!
但是,算法在計算機中是非常重要的,可以說是人類智慧的結晶。
是以呢,這些很重要很基礎的算法,貓妹決定簡單記錄下。
還記得高斯小時候的故事嗎?
求計算1+2+。。。+100的和。
如果一個一個加,當然可以,但容易出錯,而且非常耗費時間。
如果按照高斯的方法呢?
簡單,而且不容易出錯。
這就是算法,同一個問題,不同的解題思路。
有的算法效率高,有的算法效率低。
有的算法容易了解,有的算法思路實在是高。
貓爸小時候,還是個國小生,90年代。
有一次臨近春節,他的玩伴和他做了一個遊戲,讓他心中藏一個數字,1000之内的整數。
他隻問幾個問題,貓爸隻需要回答是或者不是,他就能猜出數字。
貓爸一開始覺得不可能,但是他的好友的确幾次都猜對了。
貓爸覺得挺神奇的,但是不知道咋回事。
他的問題就是将數的範圍逐漸縮小,每次縮小一半,也每次靠近貓爸心中的那個數。
這其實就是諸葛亮猜數字的故事。
諸葛亮召集将士,讓他們從1-1024中選出一個整數記在心裡。然後諸葛亮會問他們10個問題,他們隻需回答:“是”或“不是”,最終諸葛亮就能得出他們心中所想的數。
如問一謀士:“你選的數大于512?”謀士答:“不是”,之後9個問題過後,諸葛亮得出謀士所選的數是1,謀士大為吃驚,這的确是他想的數。
方法就是把1024一半一半地取,取到第十次時就是1。根據這個原理去提10個問題就能找到别人心中所想的數。
這裡面蘊含的算法就是二分法。
什麼是二分法
二分法是一種計算機算法,也稱為折半搜尋或者二分搜尋法。
它是一種在有序集合中查找特定值的算法。
該算法是通過将有序集合不斷地二分為兩半來實作的,進而查找到所需的元素。
簡而言之,它是一種減少搜尋區域的方法,進而使得搜尋時間更快。
二分法思想
二分法是一種高效的搜尋算法,适用于有序資料集的查找。
二分法的思想是不斷将搜尋區域二分為兩個部分,直到找到目标元素或者搜尋區域為空。
其基本思想是将待查找區間不斷縮小一半,直到找到目标元素或者确定目标元素不存在。
具體步驟如下:
1)首先,找到清單的中間元素。
2)如果中間元素是目标元素,則停止搜尋。
3)如果目标元素比中間元素小,則在中間元素的左邊繼續搜尋。
4)如果目标元素比中間元素大,則在中間元素的右邊繼續搜尋。
5)重複以上步驟,直到找到目标元素或者搜尋區域為空。
二分法的時間複雜度
二分查找對有序清單的時間複雜度是 O(log n),其中 n 是清單的長度。
相對于線性搜尋,二分查找效率更高,特别是當搜尋區域比較大的時候。
二分法舉例
Python語言非常适合實作二分法算法,其實作代碼非常簡單。
參考程式如下:
def binary_search(arr, low, high, target):
if high >= low:
mid = (high + low) // 2
#如果目标元素等于中間元素,則找到了目标元素
if arr[mid] == target:
return mid
#如果目标元素比中間元素小,則在左邊繼續查找
elif arr[mid] > target:
return binary_search(arr, low, mid - 1, target)
#如果目标元素比中間元素大,則在右邊繼續查找
else:
return binary_search(arr, mid + 1, high, target)
else:#元素不存在于數組中
return -1
if __name__ == '__main__':
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
target = 5
result = binary_search(arr, 0, len(arr)-1, target)
if result != -1:
print(f"元素在索引為 {result} 的位置")
else:
print("元素不在數組中")
我們首先定義一個`binary_search()`函數,該函數采用遞歸的方式實作二分查找。
參數`arr`是一個有序數組,參數`low`和參數`high`是數組中的兩個索引,分别表示最低索引和最高索引。
參數`target`是要查找的元素。
在`binary_search()`函數中,先判斷是否達到基準情況(即`high >= low`),如果已經到達基準情況,再判斷目标元素是否等于中間元素(這裡的中間元素是通過`mid`索引獲得的)。如果目标元素等于中間元素,則傳回中間元素的索引。
如果目标元素比中間元素小,則遞歸地查找左半邊。
如果目标元素比中間元素大,則遞歸地查找右半邊。
最後,我們以一個有序數組`arr`和要查找的元素`target`調用`binary_search()`函數。
如果函數傳回的結果不為-1,則說明目标元素在數組中,列印該元素的索引值;否則,列印該元素不存在數組中。
我們可以看到,對于有序數組,二分查找比線性查找具有更好的時間複雜度。
當數組規模較大時,二分查找的時間複雜度更比線性查找的時間複雜度快很多。
在實際開發中,如果要在一個有序數組或清單中查找元素,應優先考慮使用二分查找算法。
好了,我們今天就學到這裡吧!
如果遇到什麼問題,咱們多多交流,共同解決。
我是貓妹,咱們下次見!