算法圖解第二章筆記與習題(選擇排序)
文章目錄
2.2 數組和鏈表
2.2.1 鏈表
- 鏈表在內存中通過每個元素存儲下一個元素的地址,使得一系列隨機的內存地址串在一起。
想要在鏈表中插入新的元素,只需要隨機在內存中獲取地址即可。
想要在鏈表中刪除一個元素,只需要修改前一個元素指向的地址,使其跳過要刪除的元素即可。
因此,鏈表易於插入刪除,而不易於讀取。
2.2.2 數組
- 數組在內存中直接獲取一塊連續的地址,來存儲數據。當數據量超過已有地址時,將無法繼續存儲,需要搬遷整個數組。
由於數組的內存地址是連續的,所以十分易於讀取。但並不容易插入和刪除。
2.2.3 數組和鏈表的讀取、插入和刪除操作的時間複雜度
- | 數組 | 鏈表 |
---|---|---|
讀取 | ||
插入 | ||
刪除 |
2.3 選擇排序
# 找出數組中的最小元素
def findSmallest(arr):
# 存儲最小的值
smallest = arr[0]
# 存儲最小元素的索引
smallest_index = 0
for i in range(1, len(arr)):
if arr[i] < smallest:
smallest_index = i
smallest = arr[i]
return smallest_index
# 排序算法
def selectionSort(arr):
newArr = []
for i in range(len(arr)):
# 找出數組中最小的元素,並將其加入到新的數組中
smallest = findSmallest(arr)
newArr.append(arr.pop(smallest))
return newArr
2.4 小結
- 需要存儲多個元素時,可使用數組或鏈表。
- 數組的元素都是連在一起的,就像一節節車廂。
- 鏈表的元素是分散開的,其中每個元素都存儲了下一個元素的地址。
- 數組的讀取速度很快。
- 鏈表的插入和刪除的速度很快。
- 在同一個數組中,所有元素的類型都必須相同(都爲int、double等)。
練習
習題2.1
- 假設你要編寫一個記賬的應用程序。你每天都將所有支出記錄下來,並在月底統計支出,算算當月花了多少錢。因此,你執行的插入操作很多,但讀取操作很少。該使用數組還是鏈表呢?
插入操作很多,但讀取操作很少。因此更適合用鏈表。
習題2.2
- 假設你要爲飯店創建一個接受顧客點菜單的應用程序。這個應用程序存儲一系列點菜單。服務員添加點菜單,而廚師去除點菜單並製作菜餚。這是一個點菜單隊列:服務員在隊尾添加點菜單,廚師取出隊列開頭的點菜單並製作菜餚。
- 你使用數組還是鏈表來實現這個隊列呢?(提示:鏈表擅長插入和刪除,而數組擅長隨機訪問。在這個應用程序中,你要執行的是哪些操作呢?)
鏈表,在這個應用程序中,使用的更多是插入和刪除,因此選擇鏈表。
習題2.3
- 我們來做一個思考實驗。假設Facebook記錄一系列用戶名,每當有用戶試圖登錄Facebook時,都查找其用戶名,如果找到就允許用戶登錄。由於經常有用戶登錄Facebook,因此需要執行大量的用戶名查找操作。假設Facebook使用二分查找算法,而這種算法要求能隨機訪問——立即獲取中間的用戶名。考慮到這一點,應使用數組還是鏈表來存儲用戶名呢?
數組,在這個思考實驗中,需求是能夠隨機訪問。而數組相比起鏈表來說,更易於查詢。
習題2.4
- 經常有用戶在Facebook註冊。假設你已決定使用數組來存儲用戶名,在插入方面數組有何缺點呢?具體地說,在數組中添加新用戶將出現什麼情況?
在插入方面,數組容易內存不足,需要的操作也比較複雜,時間複雜度爲。
具體地說,在數組中添加新用戶時,首先需要判斷剩餘的內存空間是否富足,如果不足,則需要整體搬遷數組在內存中的地址,其次需要查找元素在數組中的位置,並將在它後面的所有元素後移一位,最多需要移動 位,這也是爲什麼在數組中添加新用戶時其時間複雜度位的原因。
習題2.5
- 實際上,Facebook存儲用戶信息使用的既不是數組也不是鏈表。假設Facebook使用的是一種混合數據:鏈表數組。這個數組包含有26個元素,每個元素都指向一個鏈表。例如,該數組的第一個元素指向的鏈表包含所有以A打頭的用戶名,第二個元素指向的鏈表包含所有以B打頭的用戶名,以此類推。
- 假設Adit B在Facebook註冊,而你需要將其加入前述的數據結構中。因此,你訪問數組的第一個元素,在訪問該元素指向的鏈表,並將Adit B添加到這個鏈表的結尾。現在你要查找Zakhir H。因此你訪問第26個元素,再在它指向的鏈表(該鏈表包含所有以z打頭的用戶名)中查找Zahkir H。
- 請問,相比於數組和鏈表,這種混合數據結構的查找和插入速度更慢還是更快?你不必給出大運行時間,只需指出這種新數據結構的查找和插入速度更快還是更慢。
插入爲常數時間,實際爲(在兩個鏈表中插入)。因此比數組快,比鏈表$O(1) $稍慢,但區別不大。
查詢爲,但實際上是 ,因此比數組慢,但比鏈表快。