【從0到1學算法】 數組和鏈表

今天講最基本的數據結構,數組和鏈表。若是你已經倒背如流,能夠跳過本文或選擇查缺補漏。java

內存的工做原理

假設你正要去超市,須要寄存兩樣東西。這個超市的寄存櫃,一個抽屜只能放一個東西,因此你須要兩個抽屜。python

image

將東西分別放到了1號和2號抽屜裏。mysql

image

服務員將號碼牌給你後,就能夠去shopping了,購物完,憑號碼牌拿東西便可。這大體就是計算機內存的工做原理,計算機內存就像不少抽屜,各個抽屜都有地址,根據地址存儲和訪問數據。面試

存儲單項數據時,只須要計算機提供一個存儲地址便可。當須要存儲多項數據時,會用到兩種基本方式---數組鏈表sql

假設你要編寫一個管理待辦事項的應用,須要將這些待辦事項存儲到內存中,用數組仍是鏈表?數組

數組

使用數組,就意味着全部待辦事項在內存中都是相連的。數據結構

image

若是你如今想添加第4個待辦事項,但後面那個抽屜放着別人的東西,這就難辦了。這種狀況只能請求計算機從新分配內存(可容納4個待辦事項),再將全部事項移到那裏。學習

這裏還有個權宜之計「預留位置」:預先申請10個連續位置,以防須要添加待辦事項。這樣,只要不超過10個,就無需轉移。但它有兩個缺點:3d

1.請求額外內存可能用不上,致使浪費;blog

2.超過10個後,仍是得轉移。

這是一個不錯的措施,但不是完美的方案。對於這種問題,咱們能夠用鏈表解決。

鏈表

使用鏈表,元素則能夠存儲在內存的任何位置。

image

每一個元素都會存儲下一個元素的內存地址。好比,"吃午餐"存儲下一個元素「玩滾地球」的內存地址13,而「玩滾地球」會存儲下一個元素「喝茶」的地址22,這樣便能將這幾項數據串在一塊了。

使用鏈表,根本不須要移動元素,元素隨便放哪都行。添加新元素時,也不須要」預留位置「,只要內存足夠,就能爲鏈表分配內存。

索引

使用數組和鏈表存儲數據,咱們都會給元素編號,編號從0開始,這些元素的編號位置成爲索引。

例如,下面的數組,元素20在索引1處

image

讀取

數組-隨機訪問

正由於數組是順序存儲的,當知道起始地址,便能知道數組中全部元素的地址,支持隨機訪問(可隨機讀取任意索引位置的值)

假設有一個數組,包含5個元素,起始地址爲00,那麼咱們便能簡單推算出第5個元素的地址是04

image

鏈表-順序訪問

而鏈表呢?元素是分開存儲的,沒法推算出任意位置元素的地址,不支持隨機訪問,只能順序訪問(從第一個元素開始逐個讀取元素)。

假設有一個鏈表,存儲數值和位置以下,知道起始地址爲01,但沒法直接知道第5個元素的位置,由於不是順序存儲且每一個元素只存儲了下一個元素的地址。

image

必須從頭遍歷,直到找到第5個位置的元素01>03>05>07>08。

因此,當須要隨機訪問數組是更好的選擇。

插入元素

數組插入數據,必須將後面的元素後移(保持順序存儲),且有可能出現連續內存不足,這就得將整個數組複製到其餘地方

例如,插入「賣茶葉」到第3個位置

image

使用鏈表時,插入元素很簡單,只需修改它前一個元素的指向地址便可。

image

因此,當須要頻繁插入元素鏈表是更好的選擇。

刪除

刪除元素呢?鏈表是更好的選,由於只需修改它前一個元素的指向地址便可。

而使用數組時,刪除元素後,必須將後面的元素都向前移(保持順序存儲)。

常見操做的運行時間

image

須要注意的是,鏈表刪除元素時,當可以當即刪除元素時,運行時間才爲O(1), 由於一般咱們都記錄了鏈表的第一個和最後一個元素。其餘狀況均爲O(n),由於須要經過順序遍歷再刪除。

總結

數組

存儲位置:順序儲存。

優勢:支持隨機訪問,讀取速度快。

缺點:插入和刪除數據較慢,須要移動元素。

鏈表

存儲位置:分開儲存,每一個元素都存儲了下一個元素的地址。

優勢:插入和刪除數據快,無需移動元素,只需修改它前面元素的指向地址便可。

缺點:只支持順序訪問,讀取速度較慢。

讀取多,插入少,用數組。

讀取少,插入多,用鏈表。

但在實際應用中,數組用的更多一,由於它支持隨機讀取。


文章首發於公衆號【KEN DO EVERTHING】 本公衆號專一於java相關技術,但不限於java、mysql、python、面試技巧、生活感悟等。分享優質博文,技術乾貨,學習資源等優質內容。 歡迎關注,一塊兒學習,共成長!

相關文章
相關標籤/搜索