昨天面試官面試的時候問了我一道關於鍊錶的問題:情境如下
面試官:請說一下鍊錶跟陣列的區別?
我:陣列靜態分配記憶體,鍊錶動態分配記憶體;陣列在記憶體中連續,鍊錶不連續;陣列利用下標定位,時間複雜度為o(1),鍊錶定位元素時間複雜度o(n);陣列插入或刪除元素的時間複雜度o(n),鍊錶的時間複雜度o(1)。
根據以上分析可得出陣列和鍊錶的優缺點如下:
陣列的優點
隨機訪問性強(通過下標進行快速定位)
查詢速度快
陣列的缺點
插入和刪除效率低(插入和刪除需要移動資料)
可能浪費記憶體(因為是連續的,所以每次申請陣列之前必須規定陣列的大小,如果大小不合理,則可能會浪費記憶體)
記憶體空間要求高,必須有足夠的連續記憶體空間。
陣列大小固定,不能動態拓展
鍊錶的優點
插入刪除速度快(因為有next指標指向其下乙個節點,通過改變指標的指向可以方便的增加刪除元素)
記憶體利用率高,不會浪費記憶體(可以使用記憶體中細小的不連續空間(大於node節點的大小),並且在需要空間的時候才建立空間)
大小沒有固定,拓展很靈活。
鍊錶的缺點
不能隨機查詢,必須從第乙個開始遍歷,查詢效率低
面試官:那請說一下單鏈表和雙鏈表的區別?
我:單鏈表只有乙個指向下一結點的指標,也就是只能next
雙鏈表除了有乙個指向下一結點的指標外,還有乙個指向前一結點的指標,可以通過prev()快速找到前一結點,顧名思義,單鏈表只能單向讀取
面試官:從你的描述來看,雙鏈表的在查詢、刪除的時候可以利用二分法的思想去實現,那麼這樣效率就會大大提高,但是為什麼目前市場應用上單鏈表的應用要比雙鏈表的應用要廣泛的多呢?
單鏈表與雙鏈表的結構圖如下:
從以上結構可以得出雙鏈表具有以下優點:
1、刪除單鏈表中的某個結點時,一定要得到待刪除結點的前驅,得到該前驅有兩種方法,第一種方法是在定位待刪除結點的同時一路儲存當前結點的前驅。第二種方法是在定位到待刪除結點之後,重新從單鏈表表頭開始來定位前驅。儘管通常會採用方法一。但其實這兩種方法的效率是一樣的,指標的總的移動操作都會有2*i次。而如果用雙向鍊錶,則不需要定位前驅結點。因此指標總的移動操作為i次。
2、查詢時也一樣,我們可以借用二分法的思路,從head(首節點)向後查詢操作和last(尾節點)向前查詢操作同步進行,這樣雙鏈表的效率可以提高一倍。
可是為什麼市場上單鏈表的使用多餘雙鏈表呢?
從儲存結構來看,每個雙鏈表的節點要比單鏈表的節點多乙個指標,而長度為n就需要 n*length(這個指標的length在32位系統中是4位元組,在64位系統中是8個位元組) 的空間,這在一些追求時間效率不高應用下並不適應,因為它占用空間大於單鏈表所占用的空間;這時設計者就會採用以時間換空間的做法,這時一種工程總體上的衡量。
三分鐘搞定python基礎
庫的匯入和新增 在機器學習和人工智慧為主導的工業4.0時代,python猶如一股龍捲風襲捲著一切。python作為一門解釋性的物件導向的語言雖然在運算速度上有不足,但是相比於程式運算速度,程式專案開發速度更為重要,而且在在這個裝備氪金時代,運算速度的缺憾完全可以拿硬體來補,何況python還支援並行...
三分鐘搞定JS繼承
基本思想 通過改變prototype的指向形成例項和原型之間的原型鏈 instancesub subtype.prototype instancesuper supertype.prototype object.prototype null 子物件的原型是父物件的例項subtype.prototyp...
沉默三分鐘
網上見此真情之文,藉以自表 原文 http www.hecaitou.net p 3018 沉默三分鐘是心祭。那麼多年了,國旗終於為平民而降。那麼多天了,全民哀悼終於實現。與此同時,火炬停止傳遞,因為這不是乙個歡慶的時刻。很多年後回顧2008年,我 也許寧可它從日曆中消失。還沒有哪一年和今年一樣,才...