提交 40bd9074 编写于 作者: W wizardforcel

2020-07-09 17:10:42

上级 b2a753d4
......@@ -26,11 +26,11 @@ FIFO representation
队列是一个对象,或更具体地说,是一个允许执行以下操作的抽象数据结构(ADT):
* **排队**:将元素添加到队列的末尾
* **出队**:从队列的开头删除元素
* **IsEmpty** :检查队列是否为空
* **IsFull** :检查队列是否已满
* **偷看**:获取队列前面的值而不删除它
* `enqueue`:将元素添加到队列的末尾
* `dequeue`:从队列的开头删除元素
* **`IsEmpty`**:检查队列是否为空
* **`IsFull`**:检查队列是否已满
* `peek`:获取队列前面的值而不删除它
* * *
......
......@@ -286,6 +286,6 @@ int main() {
## 链表应用
* 动态内存分配
* 在栈和队列中实现
***中撤消软件的**功能
* 哈希表,图形
\ No newline at end of file
* 实现栈和队列
* 软件中的撤消功能
* 哈希表,图
\ No newline at end of file
......@@ -41,7 +41,7 @@ directAddressDelete(T, x)
T[x.key] = NIL
```
**直接地址表**的限制
**直接地址表的限制**
* 密钥的值应该很小。
* 键的数量必须足够小,以使其不超过数组的大小限制。
......@@ -80,7 +80,7 @@ directAddressDelete(T, x)
如果`j`是多个元素的插槽,则它包含一个指向元素列表开头的指针。 如果不存在任何元素,则`j`包含`NIL`
![Collision resolution in hash table](img/70af56ddca4680bdf43b7ac6dcef1d71.png "Collision resolution by doubly linked list.")
**Pseudocode for operations**
**操作的伪代码**
```
chainedHashSearch(T, k)
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习什么是堆数据结构。 此外,您还将找到在 C,C++ ,Java 和 Python 中进行堆操作的工作示例。
堆数据结构是满足**堆属性**的完整二叉树。 二进制堆也称为**。**
堆数据结构是满足**堆属性**的完整二叉树,也称为二叉堆。
完整的二叉树是一种特殊的二叉树,其中
......
......@@ -22,7 +22,7 @@ Fibonacci Heap
斐波那契堆的重要属性是:
1. 它是**最小堆-** [**有序**](https://cs.lmu.edu/~ray/notes/orderedtrees/) 树的集合。 (即,父母总是比子女小。)
1. 它是**最小堆** -- [**有序**](https://cs.lmu.edu/~ray/notes/orderedtrees/)树的集合。 (即,父母总是比子女小。)
2. 指针保持在最小元素节点上。
3. 它由一组标记的节点组成。 (减少按键操作)
4. 斐波那契堆中的树是无序的,但[植根于](https://mathworld.wolfram.com/RootedTree.html)
......
......@@ -25,7 +25,7 @@
1. 从当前位置删除`x`并将其添加到根列表中。
2. 如果标记了`x`,则将其标记为`false`
### 级联剪
### 级联剪
1. 如果`y`的父级不为空,请执行以下步骤。
2. 如果未标记`y`,则标记`y`
......@@ -40,7 +40,7 @@
### 示例:将 46 减少到 15。
1. 将值减小 46 到 15。
2. **剪切部分**:由于`24 ≠ nill``15 < its parent`,将其剪切并将其添加到根列表中。 **级联剪切部分**:标记为 24。
2. **剪裁部分**:由于`24 ≠ nill``15 < its parent`,将其剪裁并将其添加到根列表中。 **级联剪裁部分**:标记为 24。
![Cut and Cascading part](img/cf0f62b73b845031cd82fd9f27a414e3.png "Decrease-key operation")
......@@ -58,20 +58,20 @@
2.切部分:由于`26 ≠ nill``5<its parent`,将其剪切并将其添加到根列表中。
2.裁部分:由于`26 ≠ nill``5<its parent`,将其剪裁并将其添加到根列表中。
![Cut 5 and add it to root list](img/083dc23fc9151df0e5f8cb1283c83223.png "Decrease-key operation")
5 并将其添加到根列表
5 并将其添加到根列表
3. 级联剪部分:由于标记为 26,因此流程进入`Cut``Cascading-Cut`
`Cut(26)`:剪 26 并将其添加到根列表中,并将其标记为`false`
3. 级联剪部分:由于标记为 26,因此流程进入`Cut``Cascading-Cut`
`Cut(26)`:剪 26 并将其添加到根列表中,并将其标记为`false`
![Cut 26 and add it to root list](img/50808a768ed07c56060a1f95a6078138.png "Decrease-key operation")
26 并将其添加到根列表中。 呼叫`Cut(24)`和`Cascading-Cut(7)`。 这些操作将导致下面的树。
26 并将其添加到根列表中。 呼叫`Cut(24)`和`Cascading-Cut(7)`。 这些操作将导致下面的树。
![Cut 24 and add it to root list](img/d0bd12ec9f2f79c499e8eb94a0713b1d.png "Decrease-key operation")
......
......@@ -28,7 +28,7 @@ A Tree
节点是一个包含键或值以及指向其子节点的指针的实体。
每个路径的最后一个节点称为**叶节点或不包含指向子节点的链接/指针的外部节点**
每个路径的最后一个节点称为**叶节点**或外部节点,不包含指向子节点的链接/指针
具有至少一个子节点的节点被称为**内部节点**
......
......@@ -70,7 +70,7 @@ Degenerate Binary Tree
### 偏二叉树
偏斜的二叉树是一种病态/退化的树,其中该树由左节点或右节点支配。 因此,存在两种类型的斜二叉树**:左斜二叉树****右斜二叉树**
偏斜的二叉树是一种病态/退化的树,其中该树由左节点或右节点支配。 因此,存在两种类型的斜二叉树**左斜二叉树****右斜二叉树**
![Skewed Binary Tree](img/33a3e3ea69a23289bc2a7282f43792f3.png "Skewed Binary Tree")
......
......@@ -6,7 +6,7 @@
完整的二叉树是二叉树的一种特殊类型,其中每个父节点/内部节点都有两个或没有子节点。
适当的二叉树也称为**。**
**也称为适当的二叉树。**
![full binary tree](img/49f25c60eff30f77913dd5fa576496c1.png "Full Binary Tree")
......
......@@ -14,7 +14,7 @@
例如,解决阶乘问题的算法可能如下所示:
**问题:找到** `n`的阶乘
**问题**:找到`n`的阶乘
```
Initialize fact = 1
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习合并排序。 此外,您还将找到合并类别 C,C++ ,Java 和 Python 的工作示例。
合并排序是计算机编程中的一种“分而治之”算法。 它是最流行的排序算法之一,也是建立对构建递归算法的信心的一种好方法。
合并排序是计算机编程中的一种“分”算法。 它是最流行的排序算法之一,也是建立对构建递归算法的信心的一种好方法。
![merge sort example](img/3440debe7e017472b6e3ed61c62d7b39.png "Merge sort example")
......@@ -14,20 +14,20 @@ Merge Sort example
* * *
## 分而治之策略
## 分策略
使用[而治之技术](/dsa/divide-and-conquer),我们将一个问题分为多个子问题。 准备好每个子问题的解决方案后,我们将这些子问题的结果“组合”起来以解决主要问题。
使用[技术](/dsa/divide-and-conquer),我们将一个问题分为多个子问题。 准备好每个子问题的解决方案后,我们将这些子问题的结果“组合”起来以解决主要问题。
假设我们必须对数组`A`进行排序。 一个子问题将是对该数组的一个子节进行排序,该子节开始于索引`p`,结束于索引`r`,表示为`A[p..r]`
**除以**
如果`q``p``r`之间的中点,则我们可以将子数组`A[p..r]`分成两个数组`A[p..q]``A[q + 1..r]`
**征服**
征服步骤中,我们尝试对两个子数组`A[p..q]``A[q + 1..r]`进行排序 。 如果尚未达到基本情况,则再次划分这两个子数组,然后尝试对它们进行排序。
**解决**
解决步骤中,我们尝试对两个子数组`A[p..q]``A[q + 1..r]`进行排序 。 如果尚未达到基本情况,则再次划分这两个子数组,然后尝试对它们进行排序。
**合并**
征服步骤到达基本步骤时,我们得到`A[p..r]`数组的两个排序的子数组`A[p..q]``A[q + 1..r]`,我们通过从两个排序的子数组`A[p]`创建一个排序的数组`A[p..r]`来组合结果`A[p..q]``A[q + 1..r]`
解决步骤到达基本步骤时,我们得到`A[p..r]`数组的两个排序的子数组`A[p..q]``A[q + 1..r]`,我们通过从两个排序的子数组`A[p]`创建一个排序的数组`A[p..r]`来组合结果`A[p..q]``A[q + 1..r]`
* * *
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习快速排序的工作原理。 此外,您还将找到 C,C++ Python 和 Java 中快速排序的工作示例。
快速排序是一种基于分而治之方法的算法,其中将数组拆分为子数组,然后递归调用这些子数组以对元素进行排序。
快速排序是一种基于分方法的算法,其中将数组拆分为子数组,然后递归调用这些子数组以对元素进行排序。
* * *
......@@ -67,10 +67,10 @@
* **划分**
将数组划分为以枢轴为分割点的子部分。 小于枢轴的元素放置在枢轴的左侧,大于枢轴的元素放置在右侧。
* **征服**
* **解决**
左子部分和右子部分再次通过选择枢轴元素进行划分。 这可以通过将子部分递归传递到算法中来实现。
* **合并**
此步骤在快速排序中不起作用。 该数组已在征服步骤的末尾排序。
此步骤在快速排序中不起作用。 该数组已在解决步骤的末尾排序。
您可以在以下插图的帮助下了解快速排序的工作方式。
......
......@@ -23,7 +23,7 @@ Here, a ≥ 1 and b > 1 are constants, and f(n) is an asymptotically positive fu
渐近正函数表示对于`n`足够大的值,我们具有`f(n) > 0`
主定理用于以简单快速的方式计算递归关系的时间复杂度(分而治之算法)。
主定理用于以简单快速的方式计算递归关系的时间复杂度(分算法)。
* * *
......
......@@ -19,7 +19,7 @@
1. 迭代法
2. 递归方法
递归方法遵循[而治之](/dsa/divide-and-conquer)方法。
递归方法遵循[](/dsa/divide-and-conquer)方法。
这两种方法的一般步骤将在下面讨论。
......
# 分而治之算法
# 分算法
> 原文: [https://www.programiz.com/dsa/divide-and-conquer](https://www.programiz.com/dsa/divide-and-conquer)
#### 在本教程中,您将学习分而治之算法的工作原理。 此外,您将发现分而治之方法与其他解决递归问题的方法之间的比较。
#### 在本教程中,您将学习分治算法的工作原理。 此外,您将发现分治方法与其他解决递归问题的方法之间的比较。
**分治算法**是一种通过以下方法解决较大问题的策略
......@@ -18,17 +18,17 @@
* * *
## 分而治之算法如何工作?
## 分算法如何工作?
涉及的步骤如下:
1. **划分**:使用递归将给定问题划分为子问题。
2. **征服**:递归解决较小的子问题。 如果子问题足够小,则直接解决。
2. **解决**:递归解决较小的子问题。 如果子问题足够小,则直接解决。
3. **组合**:组合子问题的解决方案,这是递归过程的一部分,以获取实际问题的解决方案。
让我们借助示例来理解这个概念。
在这里,我们将使用分而治之的方法对数组进行排序(即[合并排序](https://www.programiz.com/dsa/merge-sort))。
在这里,我们将使用分的方法对数组进行排序(即[合并排序](https://www.programiz.com/dsa/merge-sort))。
1. 假设给定数组为:
......@@ -38,7 +38,7 @@
2. **将数组**分为两半。
2. **将数组分为两半。**
![Divide the array into two subparts](img/5a0c971b5c6ab9aa4301e705b0cd7b64.png "Divide the array into two subparts")
......@@ -54,7 +54,7 @@
3. 现在,以排序的方式组合各个元素。 在这里,**征服****结合在一起**步骤并排进行。
3. 现在,以排序的方式组合各个元素。 在这里,**解决****组合**步骤并排进行。
![Combine the subparts](img/b653acbe16f9a67e411389a6565e803b.png "Combine the subparts")
......@@ -98,15 +98,15 @@ Now, T(n) = 2T(n log n) + O(n)
* * *
## 分而治之 vs 动态方法
## 分 vs 动态方法
而治之的方法将问题分为较小的子问题,这些子问题可以递归进一步解决。 每个子问题的结果都不存储以供将来参考,而在动态方法中,每个子问题的结果均存储以供将来参考。
的方法将问题分为较小的子问题,这些子问题可以递归进一步解决。 每个子问题的结果都不存储以供将来参考,而在动态方法中,每个子问题的结果均存储以供将来参考。
当同一子问题无法多次解决时,请使用分而治之的方法。 当将来要多次使用子问题的结果时,请使用动态方法。
当同一子问题无法多次解决时,请使用分的方法。 当将来要多次使用子问题的结果时,请使用动态方法。
让我们通过一个例子来理解这一点。 假设我们试图找到斐波那契数列。 然后,
**分而治之的方法**
**分的方法**
```
fib(n)
......@@ -133,7 +133,7 @@ fib(n)
* * *
## 分而治之算法的优势
## 分算法的优势
* 使用朴素方法将两个矩阵相乘的复杂度为`O(n^3)`,而使用分治法(即 Strassen 矩阵乘法)的复杂度为`O(n^2.8074)`。 这种方法还简化了诸如河内塔之类的其他问题。
* 这种方法适用于多处理系统。
......
......@@ -65,7 +65,7 @@ function fib(n)
动态编程主要应用于递归算法。 这不是巧合,大多数优化问题都需要递归,并且将动态编程用于优化。
但是并非所有使用递归的问题都可以使用动态编程。 除非像斐波那契数列问题那样存在重叠的子问题,否则递归只能使用分而治之的方法来解决。
但是并非所有使用递归的问题都可以使用动态编程。 除非像斐波那契数列问题那样存在重叠的子问题,否则递归只能使用分的方法来解决。
这就是为什么诸如归并排序的递归算法不能使用动态编程的原因,因为子问题不会以任何方式重叠。
......
......@@ -373,6 +373,6 @@ int main() {
尽管栈是一个易于实现的简单数据结构,但它非常强大。 栈最常见的用途是:
* **反转单词**-将所有字母叠放并弹出。 由于栈的 LIFO 顺序,您将获得相反顺序的字母。
* **在编译器中**-编译器使用栈通过将表达式转换为前缀或后缀形式来计算`2 + 4 / 5 * (7 - 9)`之类的表达式的值。
* **在浏览器中**-浏览器中的“后退”按钮会将您以前访问过的所有 URL 保存在栈中。 每次您访问新页面时,它都会被添加到栈顶部。 当您按下“后退”按钮时,当前 URL 从栈中删除,并访问前一个 URL。
\ No newline at end of file
* **反转单词** - 将所有字母叠放并弹出。 由于栈的 LIFO 顺序,您将获得相反顺序的字母。
* **在编译器中** - 编译器使用栈通过将表达式转换为前缀或后缀形式来计算`2 + 4 / 5 * (7 - 9)`之类的表达式的值。
* **在浏览器中** - 浏览器中的“后退”按钮会将您以前访问过的所有 URL 保存在栈中。 每次您访问新页面时,它都会被添加到栈顶部。 当您按下“后退”按钮时,当前 URL 从栈中删除,并访问前一个 URL。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册