提交 f50546cf 编写于 作者: W wizardforcel

2020-07-09 18:08:08

上级 9f22c937
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习树数据结构。 此外,您还将了解不同类型的树以及树中使用的术语。
树是一种非线性的分层数据结构,由边连接的节点组成。
树是一种非线性的分层数据结构,由边连接的节点组成。
![tree in data structure](img/624888bed1cba06add8d3060d14d829d.png "tree")
......@@ -32,7 +32,7 @@ A Tree
具有至少一个子节点的节点被称为**内部节点**
### 边
### 边
它是任何两个节点之间的链接。
......
......@@ -40,7 +40,7 @@ struct node {
}
```
`左侧``右侧`指向的结构节点可能还有其他左右孩子,因此我们应该将它们视为子树而不是子节点。
`左侧``右侧`指向的结构节点可能还有其他左右子级,因此我们应该将它们视为子树而不是子节点。
根据这种结构,每棵树都是
......
......@@ -61,7 +61,7 @@ Comparison between full binary tree and complete binary tree
![Complete binary tree creation](img/102b22745befe498a273190379c7b4ce.png "Put the second element as a left child of the root node and the third element as the right child")
12 个是左侧孩子,9 个是右侧孩子
12 个是左侧子级,9 个是右侧子级
......@@ -70,7 +70,7 @@ Comparison between full binary tree and complete binary tree
![Complete binary tree creation](img/846541cb9b5dcce8a8f11e736bb6c9f3.png "Keep repeating until the last element is reached")
5 个是左侧孩子,6 个是右侧孩子
5 个是左侧子级,6 个是右侧子级
......
......@@ -189,7 +189,7 @@ Final tree
### 情况三
在第三种情况下,要删除的节点有两个孩子。 在这种情况下,请执行以下步骤:
在第三种情况下,要删除的节点有两个子级。 在这种情况下,请执行以下步骤:
1. 获取该节点的有序后继。
2. 将节点替换为有序后继节点。
......
......@@ -256,8 +256,8 @@ Avl tree
2. 删除节点有以下三种情况:
1. 如果`nodeToBeDeleted`是叶节点(即没有任何子节点),则删除`nodeToBeDeleted`
2. 如果`nodeToBeDeleted`有一个孩子,则用该孩子的内容替换`nodeToBeDeleted`的内容。 移走孩子
3. 如果`nodeToBeDeleted`有两个孩子,则找到`nodeToBeDeleted`的有序继承人`w`(即,在右子树中具有键的最小值的节点)。
2. 如果`nodeToBeDeleted`有一个子级,则用该子级的内容替换`nodeToBeDeleted`的内容。 移走子级
3. 如果`nodeToBeDeleted`有两个子级,则找到`nodeToBeDeleted`的有序继承人`w`(即,在右子树中具有键的最小值的节点)。
![finding the successor](img/7bcd32387ce7a967bde7f3b1775cd5e2.png "finding the successor")
......
......@@ -91,9 +91,9 @@ B 树中的删除操作主要有三种情况。
### 情况三
在这种情况下,树的高度会缩小。 如果目标键位于内部节点中,并且键的删除导致节点中键的数量减少(即少于所需的最小数量),则寻找有序前驱和有序后继。 如果两个孩子都包含最少数量的钥匙,则无法进行借用。 这导致情况二(3),即合并孩子
在这种情况下,树的高度会缩小。 如果目标键位于内部节点中,并且键的删除导致节点中键的数量减少(即少于所需的最小数量),则寻找有序前驱和有序后继。 如果两个子级都包含最少数量的钥匙,则无法进行借用。 这导致情况二(3),即合并子级
同样,寻找同胞借用钥匙。 但是,如果同级也只有最少数量的键,则将同级节点与父级合并。 相应地安排孩子们(增加顺序)。
同样,寻找同胞借用钥匙。 但是,如果同级也只有最少数量的键,则将同级节点与父级合并。 相应地安排子级们(增加顺序)。
![Deleting an internal node](img/ba8ef21f239cb244498fe255646e1994.png "Deleting an internal node")
......
......@@ -76,7 +76,7 @@ B+ tree
2. 由于`k > 25`,请找到合适的孩子
2. 由于`k > 25`,请找到合适的子级
![B+ tree search](img/8c3928ad66bfea026b07d770b9e989b7.png "B+ tree search")
......@@ -89,7 +89,7 @@ B+ tree
4. 由于`k≥45`,因此请找到合适的孩子
4. 由于`k≥45`,因此请找到合适的子级
![B+ tree search](img/35985bda9a2e7fdbe5b780dee68c7c55.png "B+ tree search")
......
......@@ -207,7 +207,7 @@ DNA 是携带遗传信息的分子。 它们由较小的单位组成,用罗马
`+`代替的`*`运算符进行了大量更改。
考虑到模式为 100 个字符,您的算法现在快了 100 倍。 如果您的图案包含 1000 个字符,那么 KMP 算法的速度将提高近 1000 倍。 也就是说,如果您能够在 1 秒内找到模式的出现,那么现在只需要 1 毫秒。 我们也可以用另一种方式。 您可以同时匹配 1000 条相似长度的链,而不是匹配 1 条链。
考虑到模式为 100 个字符,您的算法现在快了 100 倍。 如果您的模式包含 1000 个字符,那么 KMP 算法的速度将提高近 1000 倍。 也就是说,如果您能够在 1 秒内找到模式的出现,那么现在只需要 1 毫秒。 我们也可以用另一种方式。 您可以同时匹配 1000 条相似长度的链,而不是匹配 1 条链。
而且有无数这样的故事...
......
......@@ -149,7 +149,7 @@ Red Black Tree
2.`y-z`上右旋转。
2.`y-z`右旋转。
![left-right rotate](img/8ecc5bd81a8bb1bb74c13ab4ce357535.png "right rotate z-y")
......@@ -159,7 +159,7 @@ Red Black Tree
在左右旋转时,排列首先移至右侧,然后移至左侧。
1.`x-y`上右旋转。
1.`x-y`右旋转。
![right-left rotate](img/68cc4199fe614338cf02789a3cd16679.png "right rotate x-y")
......@@ -182,7 +182,7 @@ Red Black Tree
插入新节点时,新节点始终作为红色节点插入。 插入新节点后,如果树违反了红黑树的属性,则执行以下操作。
1. 重新着色
2.
2. 重新旋
* * *
......@@ -218,7 +218,7 @@ Red Black Tree
如果`newNode`的插入违反了此属性,则此算法用于维护红黑树的属性。
1. 进行以下操作,直到`newNode p`的父级为红色。
2. 如果`p``z``grandParent gP`的左孩子,请执行以下操作。
2. 如果`p``z``grandParent gP`的左子级,请执行以下操作。
**情况一**
1. 如果`z``gP`的右子色为红色,则将`gP`的两个子级分别设置为黑色和红色。
2.`gP`分配给`newNode`
......@@ -247,11 +247,11 @@ Red Black Tree
### 删除节点的算法
1.`nodeToBeDeleted`的颜色保存在`origrinalColor`中。
2. 如果`nodeToBeDeleted`的左孩子`NULL`
2. 如果`nodeToBeDeleted`的左子级`NULL`
1.`nodeToBeDeleted`的右子代分配给`x`
2.`x`移植`nodeToBeDeleted`
3. 否则,如果`nodeToBeDeleted`的右子对象是`NULL`
1.`nodeToBeDeleted`的左孩子分配到`x`中。
1.`nodeToBeDeleted`的左子级分配到`x`中。
2.`x`移植`nodeToBeDeleted`
4. 其他
1.`noteToBeDeleted`的右子树的最小值分配到`y`中。
......@@ -282,7 +282,7 @@ Red Black Tree
以下算法保留了红黑树的属性。
1. 执行以下操作,直到`x`不是树的根并且`x`的颜色为黑色
2. 如果`x`是其父级的左孩子
2. 如果`x`是其父级的左子级
1.`w`分配给`x`的同级。
2. 如果`x`的父级的右子是红色,则
**情况 I**
......
......@@ -11,7 +11,7 @@
插入新节点时,新节点始终作为红色节点插入。 插入新节点后,如果树违反了红黑树的属性,则执行以下操作。
1. 重新着色
2.
2. 重新旋
* * *
......@@ -83,7 +83,7 @@
如果插入`newNode`违反了该属性,则此算法用于维护红黑树的属性。
1. 执行以下操作,直到`newNode p`的父代变为红色。
2. 如果`p``newNode``grandParent gP`的左孩子,请执行以下操作。
2. 如果`p``newNode``grandParent gP`的左子级,请执行以下操作。
**情况一**
1. 如果`newNode``gP`的右子级的颜色是红色,则将`gP`的子级的颜色都设置为黑色,将`gP`的颜色都设置为红色。
......
......@@ -32,7 +32,7 @@
3. 如果`nodeToBeDeleted`的左孩子`NULL`
3. 如果`nodeToBeDeleted`的左子级`NULL`
1.`nodeToBeDeleted`的右子代分配给`x`
![deletion in a red-black tree](img/1c1d4bccc79c9652144a6fe39b602418.png "assign x to the rightChild")
......@@ -50,9 +50,9 @@
4. 否则,如果`nodeToBeDeleted`的右子对象是`NULL`
1.`nodeToBeDeleted`的左孩子分配到`x`中。
1.`nodeToBeDeleted`的左子级分配到`x`中。
2.`x`移植`nodeToBeDeleted`
5. 其他
5. 否则
1.`noteToBeDeleted`的右子树的最小值分配到`y`中。
2.`和`的颜色保存在`originalColor`中。
3.`y``rightChild`分配到`x`中。
......@@ -81,7 +81,7 @@
以下算法保留了红黑树的属性。
1. 执行以下操作,直到`x`不是树的根并且`x`的颜色为黑色
2. 如果`x`是其父级的左孩子
2. 如果`x`是其父级的左子级
1.`w`分配给`x`的兄弟。
![deletion in a red-black tree](img/b80a459b7a0d32e17b962f48bd1cb6d2.png "assigning w")
......
......@@ -8,7 +8,7 @@
让我们尝试通过一个例子来理解这一点。 在 facebook 上,一切都是节点。 包括用户,照片,相册,事件,组,页面,评论,故事,视频,链接,注释...任何有数据的都是节点。
每个关系都是从一个节点到另一个节点的一条边。 无论您发布照片,加入群组(如页面等),都会为该关系创建新的边
每个关系都是从一个节点到另一个节点的一条边。 无论您发布照片,加入群组(如页面等),都会为该关系创建新的边。
![graph data structure explained using facebook's example. Users, groups, pages, events, etc. are represented as nodes and their relationships - friend, joining a group, liking a page are represented as links between nodes](img/85cd94ece58965f7646c95b7496418ba.png "Example of graph data structure")
......@@ -16,12 +16,12 @@ Example of graph data structure
然后,所有的 facebook 都是这些节点和边的集合。 这是因为 facebook 使用图形数据结构来存储其数据。
然后,所有的 facebook 都是这些节点和边的集合。 这是因为 facebook 使用图形数据结构来存储其数据。
更准确地说,图是一种数据结构`(V, E)`,由
* 顶点`V`的集合
*`E`的集合,表示为有序的顶点对`(u, v)`
*`E`的集合,表示为有序的顶点对`(u, v)`
![a graph contains vertices that are like points and edges that connect the points](img/abf9b1eff586dcbc635ccd0aedc5d1c0.png "Vertices and edges")
......@@ -43,7 +43,7 @@ G = {V, E}
* **相邻**:如果存在一条连接顶点的边,则该顶点被称为与另一个顶点相邻。 顶点 2 和 3 不相邻,因为它们之间没有边。
* **路径**:一条允许您从顶点`A`到顶点`B`的边序列称为路径。 0-1、1-2 和 0-2 是从顶点 0 到顶点 2 的路径。
* **有向图**:其中边`(u, v)`不一定意味着也有边`(v, u)`的图。 该图中的边缘由箭头表示,以显示边缘的方向。
* **有向图**:其中边`(u, v)`不一定意味着也有边`(v, u)`的图。 该图中的边由箭头表示,以显示边的方向。
* * *
......
......@@ -6,7 +6,7 @@
在学习生成树之前,我们需要了解两个图:无向图和连接图。
**无向图**是其中边缘没有指向任何方向的图(即,边缘是双向的)。
**无向图**是其中边没有指向任何方向的图(即,边是双向的)。
![Undirected Graph](img/7167ad2a18ac65a155f0105133975f95.png "Undirected Graph")
......@@ -28,7 +28,7 @@ Connected Graph
生成树是无向图和连通图的子图,其中包括图的所有顶点,这些顶点的边数最少。 如果缺少顶点,则它不是生成树。
可以分配权重,也可以不分配权重。
边可以分配权重,也可以不分配权重。
可以从完整图形创建的具有`n`顶点的生成树总数等于`n^(n-2)`
......@@ -90,7 +90,7 @@ A spanning tree
## 最小生成树
最小生成树是其中边的权重之和尽可能最小的生成树。
最小生成树是其中边的权重之和尽可能最小的生成树。
* * *
......
......@@ -36,7 +36,7 @@ Kosaraju 的算法基于[两次实现的深度优先搜索算法](/dsa/graph-dfs
涉及三个步骤。
1. 在整个图上执行深度优先搜索。
1. 在整个图上执行深度优先搜索。
让我们从顶点 0 开始,访问其所有子顶点,并将访问的顶点标记为完成。 如果顶点通向已经访问过的顶点,则将该顶点推入栈。
......
......@@ -12,8 +12,8 @@
一个标准的 DFS 实现将图形的每个顶点分为以下两类之一:
1. 来过
2.造访
1. 已访问
2.访问
该算法的目的是将每个顶点标记为已访问,同时避免循环。
......@@ -354,6 +354,6 @@ DFS 算法的时间复杂度以`O(V + E)`的形式表示,其中`V`是节点数
## DFS 算法应用
1. 寻找路径
2. 测试图是否为二
2. 测试图是否为二
3. 用于查找图的强连接组件
4. 用于检测图中的周期
\ No newline at end of file
4. 用于检测图中的循环
\ No newline at end of file
......@@ -12,8 +12,8 @@
标准的 BFS 实现将图形的每个顶点分为以下两类之一:
1. 来过
2.造访
1. 已访问
2.访问
该算法的目的是将每个顶点标记为已访问,同时避免循环。
......
......@@ -8,9 +8,9 @@
* * *
## 为什么人们在现实生活中会遇到负重的边
## 为什么人们在现实生活中会遇到负重的边?
起初负负边似乎没有用,但它们可以解释很多现象,例如现金流,化学反应中释放/吸收的热量等。
起初负负边似乎没有用,但它们可以解释很多现象,例如现金流,化学反应中释放/吸收的热量等。
例如,如果从一种化学品 A 到达另一种化学品 B 的方式不同,则每种方法都会具有涉及散热和吸收的副反应。
......
......@@ -456,4 +456,4 @@ int main() {
在以下情况下使用冒泡排序:
1. 代码的复杂程度无关紧要。
2. 首选短代码。
\ No newline at end of file
2. 短代码是首选的。
\ No newline at end of file
......@@ -25,7 +25,7 @@ Working of Radix Sort
1. 找到数组中最大的元素,即`max`。 令`X``max`中的位数。 计算`X`是因为我们必须遍历所有元素的所有重要位置。
在此数组`[121, 432, 564, 23, 1, 45, 788]`中,我们拥有最大的数字 788。它具有 3 位数字。 因此,循环应上升到百位(3 次)。
2. 现在,一个接一个地走过每个重要的地方。
2. 现在,一个接一个地访问每个重要的地方。
使用任何稳定的排序技术在每个重要位置对数字进行排序。 我们为此使用了计数排序。
......@@ -45,7 +45,7 @@ Working of Radix Sort
4. 最后,根据百位数字对元素进行排序。
4. 最后,根据百位数字对元素进行排序。
![Selection Sort Step](img/b022db2672932eb8eb38283f96639087.png "Selection Sort Step")
......
......@@ -34,7 +34,7 @@ Array to be searched for
3. 否则,返回`未找到`
3. 否则,返回`"not found"`
* * *
......
......@@ -16,7 +16,7 @@
二分搜索算法可以通过以下两种方式实现。
1. 迭代法
1. 迭代
2. 递归方法
递归方法遵循[分治](/dsa/divide-and-conquer)方法。
......@@ -63,7 +63,7 @@
8. 找到`x = 4`。 找到
8. 找到`x = 4`。
![found Binary Search](img/c2c276e600a88ce46fbbe1fe1860631a.png "found")
......
......@@ -30,7 +30,7 @@ Flow network graph
### 剩余容量
从最大容量中减去流量后的边容量。
从最大容量中减去流量后的边容量。
* * *
......@@ -40,7 +40,7 @@ Flow network graph
1. 将所有边中的流初始化为 0。
2. 当源和接收器之间存在增加路径时,将此路径添加到流中。
3. 更新残差图。
3. 更新剩余图。
如果需要,我们还可以考虑反向路径,因为如果不考虑反向路径,则可能永远找不到最大流量。
......@@ -66,7 +66,7 @@ Flow network graph example
三个边之间的最小容量为 2(`B-T`)。 基于此,为每个路径更新`流量/容量`。
三个边之间的最小容量为 2(`B-T`)。 基于此,为每个路径更新`流量/容量`。
![Update the capacities](img/4e131b7ccdbaa2eb60500c1ff2e4d071.png "Update the capacities")
......@@ -74,7 +74,7 @@ Flow network graph example
2. 选择其他路径`S-D-C-T`。 这些边之间的最小容量为 3(`S-D`)。
2. 选择其他路径`S-D-C-T`。 这些边之间的最小容量为 3(`S-D`)。
![Find next path](img/f32b40ad2b798c80e29c88f81e4cec3e.png "Find next path")
......@@ -90,7 +90,7 @@ Flow network graph example
3. 现在,让我们考虑反向路径`B-D`。 选择路径`S-A-B-D-C-T`。 边之间的最小剩余容量为 1(`D-C`)。
3. 现在,让我们考虑反向路径`B-D`。 选择路径`S-A-B-D-C-T`。 边之间的最小剩余容量为 1(`D-C`)。
![Find next path](img/dbaf48642bfe9207684d352b8a522186.png "Find next path")
......@@ -109,7 +109,7 @@ Flow network graph example
分别考虑正向和反向路径的容量。
4. 将所有流量相加,`2 + 3 + 1 = 6`,这是网络流上的最大可能流量。
请注意,如果任何边的容量已满,则无法使用该路径。
请注意,如果任何边的容量已满,则无法使用该路径。
* * *
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习 Kruskal 的算法如何工作。 此外,您还将找到 C,C++ ,Java 和 Python 中 Kruskal 算法的工作示例。
Kruskal 算法是一种[最小生成树](/dsa/spanning-tree-and-minimum-spanning-tree#minimum-spanning)算法,该算法将图形作为输入,并找到该图形的边子集,
Kruskal 算法是一种[最小生成树](/dsa/spanning-tree-and-minimum-spanning-tree#minimum-spanning)算法,该算法将图形作为输入,并找到该图形的边子集,
* 形成包括每个顶点的树
* 在可以从图中形成的所有树中具有最小的权重总和
......@@ -15,12 +15,12 @@ Kruskal 算法是一种[最小生成树](/dsa/spanning-tree-and-minimum-spanning
它属于称为[贪婪算法](http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/Greedy/greedyIntro.htm)的一类算法,该算法可以找到局部最优值,以期找到全局最优值。
我们从权重最低的边缘开始,不断增加边缘直到达到目标。
我们从权重最低的边开始,不断增加边直到达到目标。
实现 Kruskal 算法的步骤如下:
1.轻到重的所有边缘排序
2. 选取权重最低的边并将其添加到生成树。 如果添加边创建了一个循环,则拒绝该边。
1.小到大排序所有边
2. 选取权重最低的边并将其添加到生成树。 如果添加边创建了一个循环,则拒绝该边。
3. 继续添加边,直到我们到达所有顶点。
* * *
......@@ -541,7 +541,7 @@ int main() {
## Kruskal vs Prim 算法
[Prim 算法](/dsa/prim-algorithm)是另一种流行的最小生成树算法,它使用不同的逻辑来查找图的 MST。 Prim 的算法不是从边缘开始,而是从顶点开始,并不断添加树中没有的权重最低的边缘,直到所有顶点都被覆盖为止。
[Prim 算法](/dsa/prim-algorithm)是另一种流行的最小生成树算法,它使用不同的逻辑来查找图的 MST。 Prim 的算法不是从边开始,而是从顶点开始,并不断添加树中没有的权重最低的边,直到所有顶点都被覆盖为止。
* * *
......
......@@ -377,7 +377,7 @@ int main() {
## 普里姆斯与克鲁斯卡尔算法
[Kruskal 算法](/dsa/kruskal-algorithm)是另一种流行的最小生成树算法,它使用不同的逻辑来查找图的 MST。 Kruskal 的算法不是从顶点开始,而是对所有边缘从低权重到高边缘进行排序,并不断添加最低边缘,而忽略那些会产生循环的边缘
[Kruskal 算法](/dsa/kruskal-algorithm)是另一种流行的最小生成树算法,它使用不同的逻辑来查找图的 MST。 Kruskal 的算法不是从顶点开始,而是对所有边从低权重到高边进行排序,并不断添加最低边,而忽略那些会产生循环的边
* * *
......
......@@ -76,11 +76,11 @@ Initial string
8. 对于每个非叶节点,将 0 分配给左边缘,将 1 分配给右边缘
8. 对于每个非叶节点,将 0 分配给左边,将 1 分配给右边
![huffman coding](img/a17c1eca1f7df0e18ada2ed34c13f014.png "getting the sum of the least numbers")
将 0 分配给左边缘,将 1 分配给右边缘
将 0 分配给左边,将 1 分配给右边
......
......@@ -40,7 +40,7 @@ Rabin-Karp 算法是一种用于使用哈希函数搜索/匹配文本中的模
3. `m`图案的长度,`n`是文本的长度。 在此,`m = 10 and n = 3.`
3. `m`模式的长度,`n`是文本的长度。 在此,`m = 10 and n = 3.`
`d`为输入集中的字符数。 在这里,我们采用了输入集`{A, B, C, ..., J}`。 因此,`d = 10`。 您可以为`d`假定任何合适的值。
4. 让我们计算模式的哈希值。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册