|
92 | 92 | * 插入: `O(log(n))`
|
93 | 93 | * 删除: `O(log(n))`
|
94 | 94 |
|
95 |
| -<img src="/Images/BST.png?raw=true" alt="Binary Search Tree" width="400" height="500"> |
| 95 | +<img src="/images/BST.png?raw=true" alt="Binary Search Tree" width="400" height="500"> |
96 | 96 |
|
97 | 97 | ### Trie
|
98 | 98 | * 字典树,又称基数树或者前缀树,能够用于存储键为字符串的动态集合或者关联数组的搜索树。树中的节点并没有直接存储关联键值,而是该节点在树中的挂载位置决定了其关联键值。某个节点的所有子节点都拥有相同的前缀,整棵树的根节点则是空字符串。
|
99 | 99 |
|
100 |
| - |
| 100 | + |
101 | 101 |
|
102 | 102 | ### Fenwick Tree
|
103 | 103 | * 树状数组又称 Binary Indexed Tree,其表现形式为树,不过本质上是以数组实现。数组中的下标代表着树中的顶点,每个顶点的父节点或者子节点的下标能够通过位运算获得。数组中的每个元素包含了预计算的区间值之和,在整棵树更新的过程中同样会更新这些预计算的值。
|
104 | 104 | * 时间复杂度:
|
105 | 105 | * 区间求值: `O(log(n))`
|
106 | 106 | * 更新: `O(log(n))`
|
107 | 107 |
|
108 |
| - |
| 108 | + |
109 | 109 |
|
110 | 110 | ### Segment Tree
|
111 | 111 | * 线段树是用于存放间隔或者线段的树形数据结构,它允许快速的查找某一个节点在若干条线段中出现的次数.
|
112 | 112 | * 时间复杂度:
|
113 | 113 | * 区间查询: `O(log(n))`
|
114 | 114 | * 更新: `O(log(n))`
|
115 | 115 |
|
116 |
| - |
| 116 | + |
117 | 117 |
|
118 | 118 | ### Heap
|
119 | 119 | * 堆是一种特殊的基于树的满足某些特性的数据结构,整个堆中的所有父子节点的键值都会满足相同的排序条件。堆更准确地可以分为最大堆与最小堆,在最大堆中,父节点的键值永远大于或者等于子节点的值,并且整个堆中的最大值存储于根节点;而最小堆中,父节点的键值永远小于或者等于其子节点的键值,并且整个堆中的最小值存储于根节点。
|
|
122 | 122 | * 插入: `O(log(n))`
|
123 | 123 | * 移除最大值 / 最小值: `O(log(n))`
|
124 | 124 |
|
125 |
| -<img src="/Images/heap.png?raw=true" alt="Max Heap" width="400" height="500"> |
| 125 | +<img src="/images/heap.png?raw=true" alt="Max Heap" width="400" height="500"> |
126 | 126 |
|
127 | 127 |
|
128 | 128 | ### Hashing
|
|
132 | 132 | * **链地址法(Separate Chaining)**: 链地址法中,每个桶是相互独立的,包含了一系列索引的列表。搜索操作的时间复杂度即是搜索桶的时间(固定时间)与遍历列表的时间之和。
|
133 | 133 | * **开地址法(Open Addressing)**: 在开地址法中,当插入新值时,会判断该值对应的哈希桶是否存在,如果存在则根据某种算法依次选择下一个可能的位置,直到找到一个尚未被占用的地址。所谓开地址法也是指某个元素的位置并不永远由其哈希值决定。
|
134 | 134 |
|
135 |
| - |
| 135 | + |
136 | 136 |
|
137 | 137 | ### Graph
|
138 | 138 | * 图是一种数据元素间为多对多关系的数据结构,加上一组基本操作构成的抽象数据类型。
|
139 | 139 | * **无向图(Undirected Graph)**: 无向图具有对称的邻接矩阵,因此如果存在某条从节点 u 到节点 v 的边,反之从 v 到 u 的边也存在。
|
140 | 140 | * **有向图(Directed Graph)**: 有向图的邻接矩阵是非对称的,即如果存在从 u 到 v 的边并不意味着一定存在从 v 到 u 的边。
|
141 | 141 |
|
142 |
| -<img src="/Images/graph.png?raw=true" alt="Graph" width="400" height="500"> |
| 142 | +<img src="/images/graph.png?raw=true" alt="Graph" width="400" height="500"> |
143 | 143 |
|
144 | 144 | ## 算法
|
145 | 145 |
|
|
152 | 152 | * 最坏时间: `O(n^2)`
|
153 | 153 | * 平均时间: `O(nlog(n))`
|
154 | 154 |
|
155 |
| - |
| 155 | + |
156 | 156 |
|
157 | 157 | #### 归并排序
|
158 | 158 | * 归并排序是典型的分治算法,它不断地将某个数组分为两个部分,分别对左子数组与右子数组进行排序,然后将两个数组合并为新的有序数组。
|
|
162 | 162 | * 最坏时间: `O(nlog(n))`
|
163 | 163 | * 平均时间: `O(nlog(n))`
|
164 | 164 |
|
165 |
| - |
| 165 | + |
166 | 166 |
|
167 | 167 | #### 桶排序
|
168 | 168 | * 桶排序将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。
|
|
172 | 172 | * 平均时间:`Θ(n + k)`
|
173 | 173 |
|
174 | 174 |
|
175 |
| - |
| 175 | + |
176 | 176 |
|
177 | 177 | #### 基数排序
|
178 | 178 | * 基数排序类似于桶排序,将数组分割到有限数目的桶中;不过其在分割之后并没有让每个桶单独地进行排序,而是直接进行了合并操作。
|
|
187 | 187 | * 深度优先算法是一种优先遍历子节点而不是回溯的算法。
|
188 | 188 | * 时间复杂度: `O(|V| + |E|)`
|
189 | 189 |
|
190 |
| - |
| 190 | + |
191 | 191 |
|
192 | 192 | #### 广度优先搜索
|
193 | 193 | * 广度优先搜索是优先遍历邻居节点而不是子节点的图遍历算法。
|
194 | 194 | * 时间复杂度: `O(|V| + |E|)`
|
195 | 195 |
|
196 |
| - |
| 196 | + |
197 | 197 |
|
198 | 198 | #### 拓扑排序
|
199 | 199 | * 拓扑排序是对于有向图节点的线性排序,如果存在某条从 u 到 v 的边,则认为 u 的下标先于 v。
|
|
203 | 203 | * **Dijkstra 算法** 用于计算有向图中单源最短路径问题。
|
204 | 204 | * 时间复杂度: `O(|V|^2)`
|
205 | 205 |
|
206 |
| - |
| 206 | + |
207 | 207 |
|
208 | 208 | #### Bellman-Ford 算法
|
209 | 209 | * **Bellman-Ford 算法**是在带权图中计算从单一源点出发到其他节点的最短路径的算法。
|
|
212 | 212 | * 最优时间: `O(|E|)`
|
213 | 213 | - 最坏时间: `O(|V||E|)`
|
214 | 214 |
|
215 |
| - |
| 215 | + |
216 | 216 |
|
217 | 217 | #### Floyd-Warshall 算法
|
218 | 218 | * **Floyd-Warshall 算法** 能够用于在无环带权图中寻找任意节点的最短路径。
|
|
225 | 225 | * **Prim 算法**是用于在带权无向图中计算最小生成树的贪婪算法。换言之,Prim 算法能够在图中抽取出连接所有节点的边的最小代价子集。
|
226 | 226 | * 时间复杂度: `O(|V|^2)`
|
227 | 227 |
|
228 |
| - |
| 228 | + |
229 | 229 |
|
230 | 230 | #### Kruskal 算法
|
231 | 231 | * **Kruskal 算法**同样是计算图的最小生成树的算法,与 Prim 的区别在于并不需要图是连通的。
|
232 | 232 | * 时间复杂度: `O(|E|log|V|)`
|
233 | 233 |
|
234 |
| - |
| 234 | + |
235 | 235 |
|
236 | 236 | ## 位运算
|
237 | 237 | * 位运算即是在位级别进行操作的技术,合适的位运算能够帮助我们得到更快地运算速度与更小的内存使用。
|
|
259 | 259 | #### 大 O 表示
|
260 | 260 | * **大 O 表示** 用于表示某个算法的上限,往往用于描述最坏的情况。
|
261 | 261 |
|
262 |
| - |
| 262 | + |
263 | 263 |
|
264 | 264 | #### 小 O 表示
|
265 | 265 | * **小 O 表示**用于描述某个算法的渐进上界,不过二者要更为紧密。
|
266 | 266 |
|
267 | 267 | #### 大 Ω 表示
|
268 | 268 | * **大 Ω 表示**用于描述某个算法的渐进下界。
|
269 | 269 |
|
270 |
| - |
| 270 | + |
271 | 271 |
|
272 | 272 | #### 小 ω 表示
|
273 | 273 | * **Little Omega Notation**用于描述某个特定算法的下界,不过不一定很靠近。
|
274 | 274 |
|
275 | 275 | #### Theta Θ 表示
|
276 | 276 | * **Theta Notation**用于描述某个确定算法的确界。
|
277 | 277 |
|
278 |
| - |
| 278 | + |
279 | 279 |
|
280 | 280 | ## 视频教程
|
281 | 281 | * Data Structures
|
|
0 commit comments