不定長數組
維護一個序列
在末尾插入/刪除均攤O(1)
任意位置插入O(n)
指定位置查詢/修改O(1)
空間O(n)
鏈表
維護一個序列
定位到第i個位置O(n)
在任意位置(已定位到該位置)插入/刪除/修改O(1)
空間O(n)
散列表
維護鍵-值對應關系或維護鍵的存在性
1.開放尋址法散列表
若已插入鍵個數小於表大小的3/4則可以認為查詢/修改/插入期望O(1),最壞O(n)若正確選擇hash函數一般不會出現
刪除只能標記刪除
一般所需空間應大於鍵個數的4/3以保證效率
2.鏈接法散列表
若表中鍵個數a,表大小n,則查詢/修改/插入/刪除期望O(1+a/n),最壞O(n),若正確選擇hash函數一般不會出現
必要時可以用平衡樹代替鏈表而做到最壞O(logn)但實用價值不大
棧
維護一些元素
支持O(1)插入和彈出元素,且保證彈出的元素是棧中最后一個插入的元素
隊列
維護一些元素
支持O(1)插入和彈出元素,且保證彈出的元素是隊列中最先插入的元素
並查集
維護一些元素以及兩兩之間是否同類(同類關系可傳遞)並支持將兩個元素所屬的類合為一類
1.並查集的森林實現
按秩合並+路徑壓縮 查詢/合並 均攤O(α(n,m))
僅按秩合並 單次操作保證O(logn)
僅路徑壓縮 單次操作保證O(logn)
2.並查集的鏈表/不定長數組/圖實現
查詢/合並 均攤O(logn)
支持遍歷某元素所在集合
樹狀數組
維護一個序列
設序列長度n,操作個數m
修改指定位置元素的值O(logn)
求指定區間元素的和O(logn)
推廣:
通過維護差分可以O(logn)區間增加指定值,查詢元素的值
維護任意滿足區間加法的運算下的前綴和
維護任意滿足區間間法的運算下的區間和
k維推廣:
空間O(nk),利用散列表動態開點可做到O(mlogkn)
單次修改/k維區間和O(logkn)
平衡樹
維護一個(非嚴格)單調序列
查詢前趨后繼/插入/刪除O(logn)
在維護size后可支持O(logn)查詢排名/小於k的元素個數
不維護序列單調性而只維護普通序列 可以支持O(logn)指定位置插入/刪除/查詢
splay可實現區間翻轉,序列的分裂合並等操作,復雜度為均攤O(logn),treap可以在期望O(logn)做到這些操作
紅黑樹具有較小的期望常數,avl樹則只在查詢時較快
利用線段樹的規則可以維護區間信息
線段樹
維護一個序列的區間信息
可支持單點/區間 修改/查詢,一般單次操作O(logn),要求維護的信息滿足結合律
對長度為d的區間內每個點一起進行修改,復雜度為O(d+logn)
合並兩棵線段樹的復雜度與合並中減少的節點數相當,按某個值分裂線段樹的復雜度為O(logn)
如果無修改操作,也可以O(nlogn)預處理,O(1)查詢區間信息
利用類似平衡樹的規則可以實現在指定位置插入/刪除O(logn)
指針實現的線段樹可以方便地可持久化/動態開點等
堆
維護一些無序元素
查詢最小值O(1)
插入元素/刪除最小值O(logn)
(已定位到指定元素)減小指定元素的值O(logn)(斐波那契堆等為均攤O(1))
可並堆可支持O(logn)合並
字典樹
維護一些串
支持O(n)插入/刪除一個長度為n的串,查詢一個串是否存在,查詢一個串是否是某個串的前綴
也可以用於實現字典操作維護鍵-值對應
通常實現需要空間O(nk),k為字符集大小,n為插入的總串長
平衡樹維護可只用O(n)空間但操作復雜度變為O(nlogk)
ST表
維護一個序列
構建時間空間均為O(nlogn)
查詢區間最大值O(1)
最大值可換為其它任意 可由兩個區間的值得出並區間的值 的運算
塊狀鏈表/塊狀數組
維護一個序列,相當於動態分塊
指定位置查詢/修改/插入/刪除/區間翻轉/區間查詢/區間修改 O(n0.5)
分塊
可以維護很多線段樹和平衡樹等無法高效實現的操作,時間復雜度一般是O(n0.5),必要時可為了平衡塊內和塊間操作的復雜度而調整這個值
利用每個塊內部元素較少和總塊數較少的特點,可以用較高的復雜度預處理/重構一個塊的信息,要求對每個塊查詢的結果可以高效合並,對每個塊可以整體標記修改
k-d樹
維護k維空間中的點 k>1
構建O(knlogn)
空間O(nk)
插入期望O(logn),如果用替罪羊樹的重構規則可以保證最壞O(log2n)
查詢/修改(每維指定區間)信息O(min(n,k2kn1-1/k))
查詢最近/最遠點/與向量最大點積/距離給定點小於定值的點期望復雜度較優,但最壞情況退化為O(n)
可持久化數據結構
一般實現方式為path copy或fat node
原數據結構有嚴格的時空復雜度,則可持久化后仍可保證復雜度
若原數據結構為線性數據結構則一般不能直接可持久化,復雜度可能虛要乘上一個logn
一般空間不可避免的會增大每次操作logn或更大,但不會超過時間復雜度
均攤復雜度在可持久化后一般最壞情況會退化
數據結構樹上推廣
通過樹鏈剖分可將形態不變的樹分解為鏈進行維護,復雜度為原數據結構乘logn
對形態不變的樹若信息符合區間減法則可以用dfs序維護子樹信息,或用樹上差分維護路徑信息,復雜度同原數據結構
link-cut tree可以支持樹形態的簡單修改操作,並可以進行鏈修改或詢問,一般復雜度為均攤O(logn),經過一些修改可以在同樣復雜度內維護子樹信息
點分治/邊分治也可用數據結構維護
嵌套數據結構
在必要時,可以把一種數據結構看做另一種數據結構維護的信息,從而將兩個數據結構進行嵌套
例如k維樹狀數組可看做樹狀數組套k-1維樹狀數組,不同的數據結構也可以互相嵌套,例如線段樹套平衡樹實現查詢區間<x的個數
由於具體嵌套方式的不同,復雜度通常是原復雜度相加或相乘,但也有例外