數據結構和算法學習筆記-數組、鏈表(上)

免責聲明,本文內容大多是對數據結構與算法之美課程的學習筆記,內容上面有很多相似之處。也不太適合初學者去直接學習和掌握,僅供有算法經驗的同學提供一些,快速回顧算法知識的支持

數組

關鍵詞:線性表(Linear List)、非線性表

定義:

數組(Array)是一種線性表數據結構。它用一組連續的內存空間,來存儲一組具有相同類型的數據。

特性:

優點:隨機訪問
缺點:刪除、插入爲保證連續性,需要大量數據搬移工作
訪問時間複雜度O(1),插入刪除時間複雜度O(n)

常見理解錯誤:

"鏈表適合插入、刪除,時間複雜度O(1);數組適合查找,時間複雜度O(1)"

實際上,這種表述是不準確的。數組是適合查找操作,但查找的時間複雜度並不是O(1)。即便是排好序的數組,你用二分查找,時間複雜度也是O(logn)。所以正確的表述應該是,數組支持隨機訪問,根據下表隨機訪問的時間複雜度爲O(1).

容器能否完全代替數組?

ArrayList最大的優勢就是可以將很多數組操作的細節封裝起來。還有動態擴容的支持

思考題:

1.基於數組的原理引出JVM的標記清除算法的核心理念。回顧一下你締結的標記清除垃圾回收算法。
2.通過一維數組的內存尋址公式,思考一下二維數組的內存尋址公式

拓展:

除了數組,鏈表、隊列、棧也是線性表結構。
二叉樹、堆、圖是非線性表

鏈表(上)

緩存淘汰策略?

先進先出FIFO(First In,First Out)、最近最少使用LFU(Least Frequently Used)、最近最少使用LRU(Least Recently Used)

三種常見的鏈表結構?

單鏈表、雙向鏈表和循環鏈表
對於雙向循環鏈表結合需要自行了解

特性:

刪除、和插入時間複雜度O(1) ,訪問時間複雜度O(n)

循環鏈表是一種特殊的單鏈表,尾結點的指針指向頭結點(課下了解:約瑟夫問題)

單鏈表的插入、刪除操作的時間複雜度已經是O(1)了,雙向鏈表還能再高效呢?

實際上這種說法是不準確的,或者說是有先決條件的。
比如:我們希望在鏈表的某個指定結點前插入一個結點。
另外對於有序鏈表,雙向鏈表的按值查詢效率也要比單鏈表高一些。因爲,我們可以記錄上次查找的位置p,每次查詢時,根據要查找的值與p的大小關係,決定是往前還是往後查找,所以平均只需要查找一般的數據。
空間換時間

如何使用單鏈表來實現LRU緩存算法?

維護一個有序單鏈表,越靠近尾部結點是越早之前訪問的。當有一個新數據被訪問時候,我們從鏈表頭開始順序遍歷鏈表。
1.如果此數據之前已經被緩存在鏈表中了,我們遍歷得到這個數據對應的結點,並講其從原來的位置刪除,然後再插入到鏈表的頭部
2.如果此數據沒有在緩存鏈表中,可以分爲兩種情況:
如果此時緩存未滿,則將此結點直接插入到鏈表的頭部;
如果此時緩存已滿,則鏈表尾結點刪除,將新的數據結點插入鏈表的頭部。
這樣就可以用鏈表實現LRU緩存了。

課後練習:如何用數組實現LRU緩存淘汰策略?

課後思考:

如何判斷一個字符串是否是迴文字符串的問題?
如果字符串是通過單鏈表來存儲的,你改如何判斷是一個迴文呢?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章