提交 1e21b9d7 编写于 作者: W wizardforcel

2020-07-09 17:38:30

上级 3669d85c
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习什么是循环队列。 此外,您还将发现在 C,C++ ,Java 和 Python 中实现循环队列。
循环队列避免了使用数组[常规队列实现中的空间浪费。](/data-structures/queue)
循环队列避免了使用数组实现的[常规队列](/data-structures/queue)中的空间浪费。
![why circular queue is needed](img/95872c16af569b7f5c6ab65003ee8360.png "Demerit of queue")
......
......@@ -26,14 +26,15 @@ The highest priority element dequeued first
## 优先队列的实现
可以使用数组,链接列表,堆数据结构或二分搜索树来实现优先级队列。 在这些数据结构中,堆数据结构提供了优先级队列的有效实现。
可以使用数组,链表,堆数据结构或二叉搜索树来实现优先级队列。 在这些数据结构中,堆数据结构提供了优先级队列的有效实现。
下面给出优先级队列的不同实现的比较分析。
|   | 窥视 | 插 | 删除 |
|   | 获取 | 插入 | 删除 |
| --- | --- | --- | --- |
| 链表 | `O(1)` | `O(n)` | `O(1)` |
| 二进制堆 | `O(1)` | `O(log n)` | `O(log n)` |
| 二搜索树 | `O(1)` | `O(log n)` | `O(log n)` |
| 二堆 | `O(1)` | `O(log n)` | `O(log n)` |
| 二搜索树 | `O(1)` | `O(log n)` | `O(log n)` |
* * *
......@@ -41,7 +42,7 @@ The highest priority element dequeued first
优先级队列的基本操作是插入,删除和查看元素。
在研究优先级队列之前,请参考[堆数据结构](/dsa/heap-data-structure),以更好地了解二进制堆,因为该二进制堆用于实现本文中的优先级队列。
在研究优先级队列之前,请参考[堆数据结构](/dsa/heap-data-structure),以更好地了解二叉堆,因为该二叉堆用于实现本文中的优先级队列。
* * *
......
......@@ -61,11 +61,11 @@ Initialize an array and pointers
3. 否则,将`front`减小 1。
4. 将新密钥`5`添加到`array[front]`中。
4. 将新`5`添加到`array[front]`中。
![Deque - insert](img/7c44cdc2f55b65e23ce5646f112fc7ae.png "Deque - insert at the front")
插入密钥
插入
......@@ -90,11 +90,11 @@ Initialize an array and pointers
4. 将新密钥`5`添加到`array[rear]`中。
4. 将新`5`添加到`array[rear]`中。
![Deque - insert at rear](img/a3f4cff56e2b07cf0401438b5e5d9a77.png "Deque - insert at the rear")
插入密钥
插入
......@@ -711,7 +711,7 @@ int main()
* * *
## 和复杂
## 和复杂
所有上述操作的时间复杂度是恒定的,即`O(1)`
......
......@@ -41,9 +41,9 @@ struct node
};
```
了解链接列表节点的结构是掌握链接列表节点的关键。
了解链表节点的结构是掌握链表节点的关键。
每个结构节点都有一个数据项和一个指向另一个结构节点的指针。 让我们创建一个包含三个项目的简单链接列表,以了解其工作原理。
每个结构节点都有一个数据项和一个指向另一个结构节点的指针。 让我们创建一个包含三个项目的简单链表,以了解其工作原理。
```
/* Initialize nodes */
......@@ -98,7 +98,7 @@ Simple linked list with three nodes
列表是最流行和最有效的数据结构之一,可以在每种编程语言(例如 C,C++ ,Python,Java 和 C# )中实现。
除此之外,链接列表是学习指针如何工作的好方法。 通过练习如何操作链表,您可以准备学习更高级的数据结构,例如图形和树。
除此之外,链表是学习指针如何工作的好方法。 通过练习如何操作链表,您可以准备学习更高级的数据结构,例如图形和树。
* * *
......@@ -274,7 +274,8 @@ int main() {
时间复杂度
|   | 最糟糕的情况 | 平均情况 |
|   | 最坏情况 | 平均情况 |
| --- | --- | --- |
| **搜索** | `O(n)` | `O(n)` |
| **插入** | `O(1)` | `O(1)` |
| **删除** | `O(1)` | `O(1)` |
......
......@@ -8,7 +8,7 @@
请记住两个要点:
* `头`指向链接列表的第一个节点
* `头`指向链表的第一个节点
* 最后一个节点的`下一个`指针是`NULL`,因此,如果下一个当前节点是`NULL`,我们已经到达链表的末尾。
在所有示例中,我们将假定链表具有三个节点`1 --->2 --->3`,其节点结构如下:
......@@ -23,9 +23,9 @@ struct node
* * *
## 如何遍历链接列
## 如何遍历链表
显示链接列表的内容非常简单。 我们继续将临时节点移至下一个节点并显示其内容。
显示链表的内容非常简单。 我们继续将临时节点移至下一个节点并显示其内容。
`temp``NULL`时,我们知道我们已经到达链表的末尾,因此我们退出了`while`循环。
......@@ -48,9 +48,9 @@ List elements are -
* * *
## 如何将元素添加到链接列
## 如何将元素添加到链表
您可以将元素添加到链接列表的开始,中间或结尾。
您可以将元素添加到链表的开始,中间或结尾。
### 添加到开头
......@@ -112,7 +112,7 @@ temp->next = newNode;
* * *
## 如何从链接列表中删除
## 如何从链表中删除
您可以从开头,结尾或特定位置删除。
......
......@@ -2,13 +2,13 @@
> 原文: [https://www.programiz.com/dsa/linked-list-types](https://www.programiz.com/dsa/linked-list-types)
#### 在本教程中,您将学习不同类型的链表。 此外,您还将在 C 中找到链接列表的实现。
#### 在本教程中,您将学习不同类型的链表。 此外,您还将在 C 中找到链表的实现。
接列表有三种常见类型。
链表有三种常见类型。
1. [单链接列](#singly)
1. [单链表](#singly)
2. [双链表](#doubly)
3. [循环链接列](#circular)
3. [循环链表](#circular)
* * *
......@@ -31,7 +31,7 @@ struct node {
}
```
可以将三个成员的单链接列表创建为:
可以将三个成员的单链表创建为:
```
/* Initialize nodes */
......@@ -81,7 +81,7 @@ struct node {
}
```
可以创建一个三人双向链接列
可以创建一个三人双向链表
```
/* Initialize nodes */
......@@ -129,9 +129,9 @@ Circular linked list
循环链表可以是单链或双链。
* 对于单链表,最后一项的下一个指针指向第一个项
* 在双向链接列表中,第一个项目的`prev`指针也指向最后一个项目。
* 在双向链表中,第一个项目的`prev`指针也指向最后一个项目。
可以将三元循环单链接列表创建为:
可以将三元循环单链表创建为:
```
/* Initialize nodes */
......
......@@ -8,7 +8,7 @@
* * *
数据通过键在键值对中表示,如下图所示。 每个数据都与一个键相关联。 密钥是指向数据的整数。
数据通过键在键值对中表示,如下图所示。 每个数据都与一个键相关联。 是指向数据的整数。
![Hash Table key and data](img/36d81123aa5bfc90c8551702e5f3e266.png "hash table data")
......@@ -20,7 +20,7 @@
* 键是小整数
* 键的数量不是太大,并且
* 没有两个数据具有相同的密钥
* 没有两个数据具有相同的
采用整数池称为总体`U = {0, 1, ……., n-1}`
......@@ -28,7 +28,7 @@
数组`T`的索引是键本身,`T`的内容是指向集合`[key, element]`的指针。 如果没有键的元素,则保留为`NULL`
![Direct addressing representation](img/df8fec0ce0a5d8fb59f5462b91bcf302.png "Direct addressing representation")
有时,密钥本身就是数据。
有时,本身就是数据。
**操作的伪代码**
......@@ -43,7 +43,7 @@ directAddressDelete(T, x)
**直接地址表的限制**
* 密钥的值应该很小。
* 的值应该很小。
* 键的数量必须足够小,以使其不超过数组的大小限制。
* * *
......@@ -60,7 +60,7 @@ directAddressDelete(T, x)
* 如果散列函数为多个键产生相同的索引,则会发生冲突。 这种情况称为碰撞。
为避免这种情况,选择了合适的哈希函数。 但是,由于`|U|>m`,不可能产生所有唯一的密钥。 因此,良好的哈希函数可能无法完全防止冲突,但是可以减少冲突次数。
为避免这种情况,选择了合适的哈希函数。 但是,由于`|U|>m`,不可能产生所有唯一的。 因此,良好的哈希函数可能无法完全防止冲突,但是可以减少冲突次数。
但是,我们还有其他解决冲突的技术。
......@@ -455,8 +455,8 @@ int main()
良好的哈希函数具有以下特征。
1. 它不应生成太大且存储桶空间小的密钥。 空间被浪费了。
2. 生成的密钥的范围不能太近,也不能太远。
1. 它不应生成太大且存储桶空间小的。 空间被浪费了。
2. 生成的的范围不能太近,也不能太远。
3. 必须尽可能减少碰撞。
用于散列的一些方法是:
......@@ -488,7 +488,7 @@ if m = 2p, then h(k) = p lower bits of m
### 通用哈希
在通用哈希中,哈希函数是独立于密钥随机选择的。
在通用哈希中,哈希函数是独立于随机选择的。
* * *
......
......@@ -15,9 +15,9 @@
堆属性是其中节点的属性
* (对于最大堆)每个节点的密钥始终大于其子节点,并且根节点的密钥在所有其他节点中最大;
* (对于最大堆)每个节点的键始终大于其子节点,并且根节点的键在所有其他节点中最大;
![Max-heap](img/de1c7e593ab8c0aa385858fa2e12d471.png "Max-heap")
* (对于最小堆)每个节点的密钥始终小于子节点,而根节点的密钥在所有其他节点中最小。
* (对于最小堆)每个节点的键始终小于子节点,而根节点的键在所有其他节点中最小。
![Min-heap](img/e3136d4ae9fc120345f6e60a19fc4b7e.png "Min-heap")
......
......@@ -4,9 +4,9 @@
#### 在本教程中,您将学习什么是斐波那契堆。 此外,您还将在 C,C++ ,Java 和 Python 中找到斐波纳契堆上不同操作的工作示例。
斐波那契堆是二项式堆的一种修改形式,其堆操作比二项式和二进制堆所支持的更有效。
斐波那契堆是二项式堆的一种修改形式,其堆操作比二项式和二堆所支持的更有效。
与二进制堆不同,一个节点可以有两个以上的子节点。
与二堆不同,一个节点可以有两个以上的子节点。
斐波那契堆称为**斐波那契**堆,因为树的构建方式使得`n`阶树中至少有`F n+2`个节点,其中`F n+2``(n + 2)nd`斐波那契数。
......@@ -80,16 +80,16 @@ Insertion Example
### 寻找
### 寻找最小值
最小元素始终由`min`指针指定。
### 联盟
### 合并
两个斐波那契堆的并集包括以下步骤。
1. 连接两个堆的根。
2. 通过从新的根列表中选择一个最小密钥来更新`min`
2. 通过从新的根列表中选择一个最小来更新`min`
![Union of two heaps](img/2036daf239e8b143c68216d100318ddc.png "Union of two heaps")
......@@ -202,7 +202,7 @@ Union of two heaps
### 减少密钥并删除节点
### 减少并删除节点
这些是[减少键和删除节点操作](https://www.programiz.com/dsa/decrease-key-and-delete-node-from-a-fibonacci-heap)中讨论的最重要的操作。
......@@ -1525,13 +1525,15 @@ int main() {
* * *
## 复杂
## 复杂
| | |
| --- | --- |
| 插入 | `O(1)` |
| 寻找 | `O(1)` |
| 联盟 | `O(1)` |
| 寻找最小值 | `O(1)` |
| 合并 | `O(1)` |
| 提取最小值 | `O(log n)` |
| 降低金钥 | `O(1)` |
| 减小键 | `O(1)` |
| 删除节点 | `O(log n)` |
* * *
......
......@@ -8,7 +8,7 @@
* * *
## 减少密钥
## 减少
在减少键操作中,键的值被减小到较低的值。
......@@ -17,8 +17,8 @@
### 降低键
1. 选择要减少的节点`x`,并将其值更改为新值`k`
2. 如果`x`的父级`y`不为空,并且父级的密钥大于`k`的密钥,则调用`C ut(x)``C ascading- C ut(y)`随后。
3. 如果`x`密钥小于`min`的密钥,则将`x`标记为`min`
2. 如果`x`的父级`y`不为空,并且父级的键大于`k`的键,则调用`C ut(x)``C ascading- C ut(y)`随后。
3. 如果`x`键小于`min`的键,则将`x`标记为`min`
### 切
......@@ -1499,7 +1499,9 @@ int main()
* * *
## 复杂
## 复杂
| 降低金钥 | `O(1)` |
| | |
| --- | --- |
| 减小键 | `O(1)` |
| 删除节点 | `O(log n)` |
\ No newline at end of file
......@@ -16,7 +16,7 @@ A Tree
## 为什么是树数据结构?
其他数据结构(例如数组,链接列表,栈和队列)是线性数据结构,可顺序存储数据。 为了在线性数据结构中执行任何操作,时间复杂度随数据大小的增加而增加。 但是,在当今的计算世界中这是不可接受的。
其他数据结构(例如数组,链表,栈和队列)是线性数据结构,可顺序存储数据。 为了在线性数据结构中执行任何操作,时间复杂度随数据大小的增加而增加。 但是,在当今的计算世界中这是不可接受的。
不同的树数据结构是非线性数据结构,因此可以更快,更轻松地访问数据。
......@@ -85,7 +85,7 @@ Creating forest from a tree
## 树的类型
1. [二叉树](http://www.programiz.com/dsa/binary-tree)
2. [搜索树](https://www.programiz.com/dsa/binary-search-tree)
2. [搜索树](https://www.programiz.com/dsa/binary-search-tree)
3. [AVL 树](https://www.programiz.com/dsa/avl-tree)
4. [B 树](http://programiz.com/dsa/b-tree)
......@@ -101,7 +101,7 @@ Creating forest from a tree
## 树木应用
*搜索树(BST)用于快速检查元素是否存在于集合中。
*搜索树(BST)用于快速检查元素是否存在于集合中。
* 堆是一种用于堆排序的树。
* 现代路由器中使用称为 Tries 的树的修改版本来存储路由信息。
* 最受欢迎的数据库使用 B 树和 T 树,这是我们上面学习的树结构的变体,用于存储其数据
......
......@@ -279,4 +279,4 @@ int main() {
## 平衡二叉树应用
* [AVL 树](https://www.programiz.com/dsa/avl-tree)
* 平衡的[二分搜索树](https://www.programiz.com/dsa/binary-search-tree)
\ No newline at end of file
* 平衡的[二叉搜索树](https://www.programiz.com/dsa/binary-search-tree)
\ No newline at end of file
# 二搜索树(BST)
# 二搜索树(BST)
> 原文: [https://www.programiz.com/dsa/binary-search-tree](https://www.programiz.com/dsa/binary-search-tree)
#### 在本教程中,您将学习二分搜索树的工作原理。 此外,您还将找到 C,C++ ,Java 和 Python 中的二分搜索树的工作示例。
#### 在本教程中,您将学习二叉搜索树的工作原理。 此外,您还将找到 C,C++ ,Java 和 Python 中的二叉搜索树的工作示例。
搜索树是一种数据结构,可快速使我们维护一个排序的数字列表。
搜索树是一种数据结构,可快速使我们维护一个排序的数字列表。
* 之所以称为二叉树,是因为每个树节点最多有两个子节点。
* 之所以称为搜索树,是因为它可用于在`O(log(n))`时间中搜索数字的存在。
将二搜索树与常规[二叉树](/data-structures/trees)分开的属性是
将二搜索树与常规[二叉树](/data-structures/trees)分开的属性是
1. 左子树的所有节点均小于根节点
2. 右子树的所有节点均大于根节点
......@@ -23,7 +23,7 @@ A tree having a right subtree with one value smaller than the root is shown to d
右边的二叉树不是二叉搜索树,因为节点“3”的右子树包含的值小于它。
您可以对二搜索树执行两个基本操作:
您可以对二搜索树执行两个基本操作:
* * *
......@@ -144,7 +144,7 @@ Image showing the importance of returning the root element at the end so that th
## 删除操作
从二搜索树中删除节点的情况有三种。
从二搜索树中删除节点的情况有三种。
### 情况一
......@@ -671,11 +671,12 @@ int main() {
* * *
## 二叉搜索树的复杂
## 二叉搜索树的复杂
### 时间复杂度
| **操作** | **最佳情况复杂度** | **平均情况复杂度** | **最坏情况的复杂性** |
| **操作** | **最佳情况复杂度** | **平均情况复杂度** | **最坏情况复杂度** |
| --- | --- | --- | --- |
| 搜索 | `O(log n)` | `O(log n)` | `O(n)` |
| 插入 | `O(log n)` | `O(log n)` | `O(n)` |
| 删除中 | `O(log n)` | `O(log n)` | `O(n)` |
......@@ -688,7 +689,7 @@ int main() {
* * *
## 二搜索树应用
## 二搜索树应用
1. 在数据库中进行多级索引
2. 用于动态排序
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习什么是 avl 树。 此外,您还将找到在 C,C++ ,Java 和 Python 的 avl 树上执行的各种操作的工作示例。
AVL 树是一种自平衡二搜索树,其中每个节点都维护额外的信息,称为平衡因子,其值为 -1、0 或 +1。
AVL 树是一种自平衡二搜索树,其中每个节点都维护额外的信息,称为平衡因子,其值为 -1、0 或 +1。
AVL 树以其发明者 Georgy Adelson-Velsky 和 Landis 得名。
......@@ -1077,9 +1077,10 @@ int main() {
* * *
## AVL 树上不同操作的复杂
## AVL 树上不同操作的复杂
| **插入** | **删除** | **搜索** |
| --- | --- | --- |
| `O(log n)` | `O(log n)` | `O(log n)` |
* * *
......
......@@ -20,20 +20,20 @@ B-tree
随着访问硬盘等物理存储介质所需的时间越来越少,对 B 树的需求也随之增加。 辅助存储设备速度较慢,容量较大。 需要这种类型的数据结构以最小化磁盘访问。
其他数据结构(例如二叉搜索树,avl 树,红黑树等)只能在一个节点中存储一个密钥。 如果必须存储大量密钥,则此类树的高度将变得非常大,并且访问时间会增加。
其他数据结构(例如二叉搜索树,avl 树,红黑树等)只能在一个节点中存储一个键。 如果必须存储大量键,则此类树的高度将变得非常大,并且访问时间会增加。
但是,B 树可以在一个节点中存储许多密钥,并且可以具有多个子节点。 这样可以大大降低高度,从而可以更快地访问磁盘。
但是,B 树可以在一个节点中存储许多,并且可以具有多个子节点。 这样可以大大降低高度,从而可以更快地访问磁盘。
* * *
## B 树属性
1. 对于每个节点`x`密钥以升序存储。
1. 对于每个节点`x`以升序存储。
2. 在每个节点中,都有一个布尔值`x.leaf`,如果`x`是叶,则为`true`
3. 如果`n`是树的顺序,则每个内部节点最多可以包含`n-1`键以及指向每个子节点的指针。
4. 除根节点外,每个节点最多可以有`n`个子节点,并且至少`n / 2`个子节点。
5. 所有叶子具有相同的深度(即树的高度`h`)。
6. 根至少有 2 个子节点,并且至少包含 1 个密钥
6. 根至少有 2 个子节点,并且至少包含 1 个
7. 如果`n≥1`,则对于任何高度为`h`且最小度为`t ≥ 2``n`键 B 树,`h ≥ log_t(n+1)/2`
* * *
......@@ -48,9 +48,9 @@ B-tree
如果为`k = the first key of the node`,则返回节点和索引。
2. 如果为`k.leaf = true`,则返回`NULL`(即未找到)。
3. 如果`k < the first key of the root node`,则递归搜索此键的左子级。
4. 如果当前节点和`k > the first key`中有多个密钥,请将`k`与该节点中的下一个密钥进行比较。
4. 如果当前节点和`k > the first key`中有多个键,请将`k`与该节点中的下一个键进行比较。
如果为`k < next key`,则搜索该键的左子键(即`k`位于第一键和第二键之间)。
否则,搜索密钥的右子级。
否则,搜索的右子级。
5. 重复步骤 1 到 4,直到到达叶子。
### 搜寻范例
......@@ -63,7 +63,7 @@ B-tree
2. 在根目录中找不到`k`,因此,请将其与根密钥进行比较。 在根节点 上找不到
2. 在根目录中找不到`k`,因此,请将其与根进行比较。 在根节点 上找不到
![Not found on the root node](img/1a4d8cbc29ae6d3f24554bb32e0c5345.png "Not found on the root node")
......
......@@ -2,7 +2,7 @@
> 原文: [https://www.programiz.com/dsa/insertion-into-a-b-tree](https://www.programiz.com/dsa/insertion-into-a-b-tree)
#### 在本教程中,您将学习如何将密钥插入 B 树。 此外,您还将找到在 C,C++ ,Java 和 Python 中将键插入 B 树的工作示例。
#### 在本教程中,您将学习如何将插入 B 树。 此外,您还将找到在 C,C++ ,Java 和 Python 中将键插入 B 树的工作示例。
在 B 树上插入元素包括两个事件:搜索适当的节点**来插入元素**,以及**拆分节点**。如有必要,插入操作始终从下往上进行。
......@@ -12,7 +12,7 @@
## 插入操作
1. 如果树为空,请分配一个根节点并插入密钥
1. 如果树为空,请分配一个根节点并插入
2. 更新节点中允许的键数。
3. 搜索适当的节点以进行插入。
4. 如果节点已满,请执行以下步骤。
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习什么是红黑树。 此外,您还将找到在 C,C++ ,Java 和 Python 的红黑树上执行的各种操作的工作示例。
红黑树是一种自平衡二搜索树,其中每个节点都包含一个额外的位,用于表示该节点的颜色,红色还是黑色。
红黑树是一种自平衡二搜索树,其中每个节点都包含一个额外的位,用于表示该节点的颜色,红色还是黑色。
一棵红黑树满足以下属性:
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习如何将新节点插入到红黑树中。 此外,您还将找到在 C,C++ ,Java 和 Python 的红黑树上执行插入的工作示例。
红黑树是一种自平衡二搜索树,其中每个节点都包含一个额外的位,用于表示该节点的颜色,红色还是黑色。
红黑树是一种自平衡二搜索树,其中每个节点都包含一个额外的位,用于表示该节点的颜色,红色还是黑色。
阅读本文之前,请参考[红黑树](/dsa/red-black-tree)上的文章。
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习如何从红黑树中删除节点。 此外,您还将找到在 C,C++ ,Java 和 Python 上对红黑树执行删除操作的工作示例。
红黑树是一种自平衡二搜索树,其中每个节点都包含一个额外的位,用于表示该节点的颜色,红色还是黑色。
红黑树是一种自平衡二搜索树,其中每个节点都包含一个额外的位,用于表示该节点的颜色,红色还是黑色。
阅读本文之前,请参考[红黑树](/dsa/red-black-tree)上的文章。
......
......@@ -71,7 +71,7 @@ Graph adjacency matrix
### 2.邻接表
邻接列表将图表示为链接列表的数组。
邻接列表将图表示为链表的数组。
数组的索引表示一个顶点,而其链表中的每个元素表示与该顶点形成边的其他顶点。
......
......@@ -4,7 +4,7 @@
#### 在本教程中,您将学习什么是邻接表。 此外,您还将在 C,C++ ,Java 和 Python 中找到邻接表的工作示例。
邻接列表将图表示为链接列表的数组。
邻接列表将图表示为链表的数组。
数组的索引表示一个顶点,而其链表中的每个元素表示与该顶点形成边的其他顶点。
......@@ -48,7 +48,7 @@ struct Graph
不要让`struct node** adjLists`淹没您。
我们只是说要存储指向`struct node*`的指针。 这是因为我们不知道图形将具有多少个顶点,因此无法在编译时创建链接列表的数组。
我们只是说要存储指向`struct node*`的指针。 这是因为我们不知道图形将具有多少个顶点,因此无法在编译时创建链表的数组。
* * *
......@@ -72,7 +72,7 @@ public:
## 邻接表 Java
我们使用 Java 集合来存储链接列表数组。
我们使用 Java 集合来存储链表数组。
```
class Graph
......
......@@ -51,7 +51,7 @@ Theta bounds the function within constants factors
## 大 O 表示法(O 表示法)
大 O 表示法表示算法运行时间的上限。 因此,它给出了算法的最坏情况的复杂
大 O 表示法表示算法运行时间的上限。 因此,它给出了算法的最坏情况的复杂
![Big-O notation](img/effc73cfa83d102b047aae80fdab01eb.png "Big-O")
......@@ -74,7 +74,7 @@ O(g(n)) = { f(n): there exist positive constants c and n0
## Ω表示法(Ω表示法)
Ω表示算法运行时间的下限。 因此,它提供了算法的最佳情况复杂
Ω表示算法运行时间的下限。 因此,它提供了算法的最佳情况复杂
![Omega Notation](img/571c8e733045af0977623af6271d187a.png "Omega")
......
......@@ -565,13 +565,15 @@ int main() {
* * *
## 贝尔曼·福特的复杂
## 贝尔曼·福特的复杂
### 时间复杂度
| | | |
| --- | --- | --- |
| 最佳情况复杂度 | `O(E)` |
| 平均情况复杂度 | `O(VE)` |
| 最坏情况的复杂性 | `O(VE)` |
| 最坏情况复杂度 | `O(VE)` |
### 空间复杂度
......
......@@ -419,7 +419,8 @@ int main() {
气泡排序是最简单的排序算法之一。 该算法实现了两个循环。
| 周期 | 比较数 |
| 周期 | 比较次数 |
| --- | --- |
| 第一 | (`n-1`) |
| 第二 | (`n-2`) |
| 第三 | (`n-3`) |
......@@ -430,7 +431,7 @@ int main() {
**复杂度**`O(n^2)`
同样,我们可以通过简单地观察循环数来分析复杂。 有 2 个循环,因此复杂度为`n*n = n^2`
同样,我们可以通过简单地观察循环数来分析复杂。 有 2 个循环,因此复杂度为`n*n = n^2`
**时间复杂度**
......
......@@ -248,18 +248,19 @@ int main() {
## 复杂
| 周期 | 比较数 |
| 周期 | 比较次数 |
| --- | --- |
| 第一 | (`n-1`) |
| 第二 | (`n-2`) |
| 第三 | (`n-3`) |
| ... | ... |
| 最后 | 1 |
比较数:`(n - 1) + (n - 2) + (n - 3) + ..... + 1 = n(n - 1) / 2`几乎等于`n^2`
比较数:`(n - 1) + (n - 2) + (n - 3) + ..... + 1 = n(n - 1) / 2`几乎等于`n^2`
**复杂度** = `O(n^2)`
同样,我们可以通过简单地观察循环数来分析复杂。 有 2 个循环,因此复杂度为`n*n = n^2`
同样,我们可以通过简单地观察循环数来分析复杂。 有 2 个循环,因此复杂度为`n*n = n^2`
**时间复杂度**
......
......@@ -230,7 +230,7 @@ int main() {
**时间复杂度**
* **最坏情况的复杂度**`O(n^2)`
假设一个数组是升序的,并且您想按降序对其进行排序。 在这种情况下,最坏情况下的复杂就会发生。
假设一个数组是升序的,并且您想按降序对其进行排序。 在这种情况下,最坏情况下的复杂就会发生。
每个元素都必须与其他每个元素进行比较,因此,对于每第`n`个元素,进行`(n-1)`个比较。
......
......@@ -344,11 +344,11 @@ int main() {
* * *
## 快速排序的复杂
## 快速排序的复杂
**时间复杂度**
* **最坏情况的复杂【大 O】**`O(n^2)`
* **最坏情况的复杂【大 O】**`O(n^2)`
当拾取的枢轴元素为最大或最小元素时,会发生这种情况。
这种情况导致枢轴元素位于已排序数组的最末端的情况。 一个子数组始终为空,而另一个子数组包含`n - 1`元素。 因此,仅在此子数组上调用快速排序。
但是,快速排序算法对于分散的数据透视表具有更好的性能。
......@@ -370,4 +370,4 @@ int main() {
* 编程语言适合递归
* 时间复杂度很重要
* 空间复杂性很重要
\ No newline at end of file
* 空间复杂度很重要
\ No newline at end of file
......@@ -311,6 +311,7 @@ int main() {
主要有四个主要循环。 (可以在函数之外找到最大值。)
| 循环 | 计数时间 |
| --- | --- |
| 第一 | `O(max)` |
| 第二 | `O(size)` |
| 第三 | `O(max)` |
......
......@@ -515,13 +515,13 @@ int main(void) {
* **最坏情况的复杂度**`O(n^2)`
当数组中有近距离的元素时,它们很可能放在同一存储桶中。 这可能会导致某些存储桶中的元素数量比其他存储桶更多。
它使复杂度取决于用于对存储区元素进行排序的排序算法。
当元素的顺序相反时,复杂将变得更加糟糕。 如果使用插入排序对存储桶中的元素进行排序,则时间复杂度变为`O(n^2)`
当元素的顺序相反时,复杂将变得更加糟糕。 如果使用插入排序对存储桶中的元素进行排序,则时间复杂度变为`O(n^2)`
* **最佳情况复杂度**`O(n+k)`
当元素在桶中均匀分布且每个桶中元素数量几乎相等时,会发生这种情况。
如果存储桶中的元素已经被分类,那么复杂就会变得更好。
如果存储桶中的元素已经被分类,那么复杂就会变得更好。
如果使用插入排序对存储桶中的元素进行排序,则最佳情况下的总体复杂度将是线性的,即。`O(n+k)``O(n)`是制造存储桶的复杂度,`O(k)`是使用在最佳情况下具有线性时间复杂度的算法对存储桶的元素进行分类的复杂度。
* **平均情况复杂度**`O(n)`
当元素在数组中随机分布时发生。 即使元素分布不均匀,存储桶排序也会在线性时间内运行。 直到铲斗尺寸的平方和在元素总数中呈线性关系时,它才成立。
当元素在数组中随机分布时发生。 即使元素分布不均匀,存储桶排序也会在线性时间内运行。 直到铲斗大小的平方和在元素总数中呈线性关系时,它才成立。
* * *
......
......@@ -487,7 +487,7 @@ Swap, Remove, and Heapify
同样,由于`build_max_heap``heap_sort`步骤是一个接一个地执行的,因此算法复杂度不会增加,而是保持在`nlog n`的顺序。
它还在`O(1)`空间复杂度中执行排序。 与快速排序相比,它具有更好的最坏情况`( O(nlog n) )`。 对于最坏的情况,快速排序具有复杂`O(n^2)`。 但是在其他情况下,快速排序速度很快。 `Introsort`是堆排序的替代方案,它结合了快速排序和堆排序以保留两者的优势:最坏情况下的堆排序速度和平均速度。
它还在`O(1)`空间复杂度中执行排序。 与快速排序相比,它具有更好的最坏情况`( O(nlog n) )`。 对于最坏的情况,快速排序具有复杂`O(n^2)`。 但是在其他情况下,快速排序速度很快。 `Introsort`是堆排序的替代方案,它结合了快速排序和堆排序以保留两者的优势:最坏情况下的堆排序速度和平均速度。
* * *
......
......@@ -156,7 +156,7 @@ int main() {
* * *
## 线性搜索的复杂
## 线性搜索的复杂
**时间复杂度**`O(n)`
......
......@@ -412,7 +412,7 @@ int main(void) {
* **最佳情况复杂度**:`O(1)`
* **平均情况复杂度**:`O(log n)`
* **最坏情况的复杂**:`O(log n)`
* **最坏情况的复杂**:`O(log n)`
**空间复杂度**
......
......@@ -110,7 +110,7 @@ function dijkstra(G, S)
## Dijkstra 算法的代码
下面给出了 Dijkstra 算法在 C++ 中的实现。 可以提高[代码](http://www.reviewmylife.co.uk/blog/2008/07/15/dijkstras-algorithm-code-in-c/)的复杂,但是抽象方法很容易将代码与算法相关联。
下面给出了 Dijkstra 算法在 C++ 中的实现。 可以提高[代码](http://www.reviewmylife.co.uk/blog/2008/07/15/dijkstras-algorithm-code-in-c/)的复杂,但是抽象方法很容易将代码与算法相关联。
[Python](#python-code)[Java](#java-code)[C](#c-code)[C++](#cpp-code)
......
......@@ -545,7 +545,7 @@ int main() {
* * *
## 克鲁斯卡尔算法的复杂
## 克鲁斯卡尔算法的复杂
Kruskal 算法的时间复杂度为:`O(E log E)`
......
......@@ -66,7 +66,7 @@
## 复杂
分治法的复杂度是使用主定理[计算的。](https://www.programiz.com/dsa/master-theorem)
分治法的复杂度是使用[主定理](https://www.programiz.com/dsa/master-theorem)计算的。
```
T(n) = aT(n/b) + f(n),
......
......@@ -86,7 +86,8 @@ Initial string
为了通过网络发送上面的字符串,我们必须发送树以及上面的压缩代码。 总大小如下表所示。
| 字符 | 频率 | 码 | 尺寸 |
| 字符 | 频率 | 编码 | 大小 |
| --- | --- | --- | --- |
| `a` | 5 | 11 | `5 * 2 = 10` |
| `b` | 1 | 100 | `1 * 3 = 3` |
| `c` | 6 | 0 | `6 * 1 = 6` |
......
......@@ -26,7 +26,7 @@ Initial graph
请按照以下步骤查找所有顶点对之间的最短路径。
1. 创建尺寸`n*n`的矩阵`A^1`,其中`n`是顶点数。 行和列的索引分别为`i``j``i``j`是图形的顶点。
1. 创建大小`n*n`的矩阵`A^1`,其中`n`是顶点数。 行和列的索引分别为`i``j``i``j`是图形的顶点。
每个单元格`A[i][j]`填充了从第`i`个顶点到第`j`个顶点的距离。 如果没有从第`i`个顶点到第`j`个顶点的路径,则该单元将保留为无穷大。
......@@ -295,7 +295,7 @@ int main() {
### 时间复杂度
有三个循环。 每个循环具有恒定的复杂。 因此,Floyd-Warshall 算法的时间复杂度为`O(n^3)`
有三个循环。 每个循环具有恒定的复杂。 因此,Floyd-Warshall 算法的时间复杂度为`O(n^3)`
### 空间复杂度
......
......@@ -55,7 +55,7 @@ Second Sequence
按照以下步骤查找最长的公共子序列。
1. 创建一个尺寸`n+1*m+1`的表,其中`n``m`分别为`X``Y`的长度。 第一行和第一列用零填充。
1. 创建一个大小`n+1*m+1`的表,其中`n``m`分别为`X``Y`的长度。 第一行和第一列用零填充。
![Longest Common Subsequence initialise table](img/7c5ac1a20c272c08b342e162992c647c.png "initialise a table")
......
......@@ -349,7 +349,7 @@ int main() {
Rabin-Karp 算法的平均情况和最佳情况复杂度为`O(m + n)`,最坏情况下的复杂度为`O(mn)`
当所有窗口出现虚假命中数时,最坏情况下的复杂就会发生。
当所有窗口出现虚假命中数时,最坏情况下的复杂就会发生。
* * *
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册