低效的「插入」和「刪除」
容器能否完全替代陣列?
為什麼大多數程式語言中,陣列要從 0 開始編號,而不是從 1 開始呢?
單鏈表雙向鍊錶
刪除給定指標指向的結點。
迴圈鍊錶
鍊錶 vs 陣列效能大比拼
如何實現乙個「棧」?
棧的應用
順序佇列和鏈式佇列
迴圈佇列
public class circularqueue
// 入隊
public boolean enqueue(string item)
// 出隊
public string dequeue()
}
應用用棧實現佇列
方法二用跳表查詢到底有多快?
跳表是不是很浪費記憶體?
高效的動態插入和刪除
刪除跳表索引動態更新
為什麼 redis 要用跳表來實現有序集合,而不是紅黑樹?
插入、刪除、查詢以及迭代輸出有序序列這幾個操作,紅黑樹也可以完成,時間複雜度跟跳表是一樣的。但是,按照區間來查詢資料這個操作,紅黑樹的效率沒有跳表高。
對於按照區間查詢資料這個操作,跳表可以做到 o(logn) 的時間複雜度定位區間的起點,然後在原始鍊錶中順序往後遍歷就可以了。這樣做非常高效。
當然,redis 之所以用跳表來實現有序集合,還有其他原因,比如,跳表更容易**實現。雖然跳表的實現也不簡單,但比起紅黑樹來說還是好懂、好寫多了,而簡單就意味著可讀性好,不容易出錯。還有,跳表更加靈活,它可以通過改變索引構建策略,有效平衡執行效率和記憶體消耗。
不過,跳表也不能完全替代紅黑樹。因為紅黑樹比跳表的出現要早一些,很多程式語言中的 map 型別都是通過紅黑樹來實現的。我們做業務開發的時候,直接拿來用就可以了,不用費勁自己去實現乙個紅黑樹,但是跳表並沒有乙個現成的實現,所以在開發中,如果你想使用跳表,必須要自己實現。
雖然跳表的**實現並不簡單,但是作為一種動態資料結構,比起紅黑樹來說,實現要簡單多了。所以很多時候,我們為了**的簡單、易讀,比起紅黑樹,我們更傾向用跳表。
雜湊函式
雜湊衝突
二次探測(quadratic probing)
雙重雜湊(double hashing)
不管採用哪種探測方法,當雜湊表中空閒位置不多的時候,雜湊衝突的概率就會大大提高。為了盡可能保證雜湊表的操作效率,一般情況下,我們會盡可能保證雜湊表中有一定比例的空閒槽位。我們用裝載因子(load factor)來表示空位的多少
鍊錶法如何打造乙個工業級水平的雜湊表?
裝載因子過大了怎麼辦?
如何避免低效的擴容?
如何選擇衝突解決方法?
鍊錶法應用舉例
裝載因子和動態擴容
雜湊衝突解決方法
雜湊函式
什麼是雜湊演算法
雜湊演算法的應用非常非常多,最常見的七個分別是安全加密、唯一標識、資料校驗、雜湊函式、負載均衡、資料分片、分布式儲存。
雜湊表兩個核心問題是雜湊函式設計和雜湊衝突解決。
資料結構與演算法 樹
後序遍歷 已知前序和中序求後序 設計 的原則 1 有且僅有乙個根節點 2 所有的子樹也滿足該要求 子樹之間不能有交集 單個節點也是一棵樹 空樹 啥資料都沒有,沒有任何節點 根節點 父節點,子節點,兄弟節點 如果兩個節點的父節點雖不相同,但是它們的父節點處在同一層次上,那麼這兩個節點是兄弟節點 葉子節...
演算法與資料結構 樹
搜尋 如上圖所示 圓圈代表結點,連線結點的線代表邊。樹由結點和連線結點的邊組成。2 有根結點的父子關係 如圖根結點為0,連線根結點0到結點4最後一條邊連線著結點1和4,則結點1稱為結點4的父節點,結點4 為結點1 的子節點。結點2,3為結點4的兄弟結點。3 根結點 沒有父節點的結點 唯一 外部結點 ...
資料結構與演算法(樹)
1 樹的定義 2 基本術語 3 樹的性質 1 二叉樹定義及特性 2 二叉樹的儲存結構 1 二叉樹遍歷 1 樹的儲存結構 2 樹 森林 二叉樹的轉換 樹轉換為二叉樹的規則 每個節點左指標指向它的第乙個孩子,右指標指向它在樹種的相鄰右兄弟。根節點沒有兄弟,所以對應二叉樹沒有右子樹。樹轉換為二叉樹的方法 ...