mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-11-10 11:09:43 +08:00
Merge 2a95643bf5
into 6509304ff6
This commit is contained in:
commit
ff03ce4fb1
@ -1,26 +1,26 @@
|
||||
# 树
|
||||
|
||||
* [二叉搜索树](binary-search-tree)
|
||||
* [AVL树](avl-tree)
|
||||
* [红黑树](red-black-tree)
|
||||
* [线段树](segment-tree) - with min/max/sum range queries examples
|
||||
* [芬威克树/Fenwick Tree](fenwick-tree) (Binary Indexed Tree)
|
||||
- [二叉搜索树](binary-search-tree/README.zh-CN.md)
|
||||
- [AVL 树](avl-tree)
|
||||
- [红黑树](red-black-tree)
|
||||
- [线段树](segment-tree) - with min/max/sum range queries examples
|
||||
- [芬威克树/Fenwick Tree](fenwick-tree) (Binary Indexed Tree)
|
||||
|
||||
在计算机科学中, **树(tree)** 是一种广泛使用的抽象数据类型(ADT)— 或实现此ADT的数据结构 — 模拟分层树结构, 具有根节点和有父节点的子树,表示为一组链接节点。
|
||||
在计算机科学中, **树(tree)** 是一种广泛使用的抽象数据类型(ADT)— 或实现此 ADT 的数据结构 — 模拟分层树结构, 具有根节点和有父节点的子树,表示为一组链接节点。
|
||||
|
||||
树可以被(本地地)递归定义为一个(始于一个根节点的)节点集, 每个节点都是一个包含了值的数据结构, 除了值,还有该节点的节点引用列表(子节点)一起。
|
||||
树的节点之间没有引用重复的约束。
|
||||
|
||||
一棵简单的无序树; 在下图中:
|
||||
|
||||
标记为7的节点具有两个子节点, 标记为2和6;
|
||||
一个父节点,标记为2,作为根节点, 在顶部,没有父节点。
|
||||
标记为 7 的节点具有两个子节点, 标记为 2 和 6;
|
||||
一个父节点,标记为 2,作为根节点, 在顶部,没有父节点。
|
||||
|
||||
![Tree](./images/tree.jpeg)
|
||||
|
||||
*Made with [okso.app](https://okso.app)*
|
||||
_Made with [okso.app](https://okso.app)_
|
||||
|
||||
## 参考
|
||||
|
||||
- [Wikipedia](https://en.wikipedia.org/wiki/Tree_(data_structure))
|
||||
- [Wikipedia](<https://en.wikipedia.org/wiki/Tree_(data_structure)>)
|
||||
- [YouTube](https://www.youtube.com/watch?v=oSWTXtMglKE&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=8)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Binary Search Tree
|
||||
|
||||
_Read this in other languages:_
|
||||
[_Português_](README.pt-BR.md)
|
||||
[_Português_](README.pt-BR.md),[_简体中文_](README.zh-CN.md)
|
||||
|
||||
In computer science, **binary search trees** (BST), sometimes called
|
||||
ordered or sorted binary trees, are a particular type of container:
|
||||
@ -30,7 +30,7 @@ The leaves are not drawn.
|
||||
|
||||
![Trie](./images/binary-search-tree.jpg)
|
||||
|
||||
*Made with [okso.app](https://okso.app)*
|
||||
_Made with [okso.app](https://okso.app)_
|
||||
|
||||
## Pseudocode for Basic Operations
|
||||
|
||||
@ -87,7 +87,6 @@ contains(root, value)
|
||||
end contains
|
||||
```
|
||||
|
||||
|
||||
### Deletion
|
||||
|
||||
```text
|
||||
@ -265,7 +264,7 @@ end postorder
|
||||
|
||||
### Time Complexity
|
||||
|
||||
| Access | Search | Insertion | Deletion |
|
||||
| Access | Search | Insertion | Deletion |
|
||||
| :-------: | :-------: | :-------: | :-------: |
|
||||
| O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) |
|
||||
|
||||
|
268
src/data-structures/tree/binary-search-tree/README.zh-CN.md
Normal file
268
src/data-structures/tree/binary-search-tree/README.zh-CN.md
Normal file
@ -0,0 +1,268 @@
|
||||
# 二叉搜索树
|
||||
|
||||
_Read this in other languages:_
|
||||
[_Português_](README.pt-BR.md),[_English_](README.md)
|
||||
|
||||
在计算机科学中, **二叉搜索树** (BST), 也称为有序二叉树或排序二叉树, 是一种特殊的容器:
|
||||
在内存中存储“元素”的数据结构(如数字,名称等)。二叉搜索树可以快速查找,添加和删除元素,也可用于
|
||||
构建动态元素集或在表中根据键查找元素值 (例:通过某人姓名找到某人的手机号)。
|
||||
|
||||
二叉搜索树为有序序列,所以在进行查找或其他操作时可以使用二分查找原理:
|
||||
在树中寻找键(或插入新键的位置)时,查找过程为: 从根到叶遍历树,通过比较
|
||||
存储在树的节点中的键来判断继续向左或向右搜索子树。 平均而言,这意味着每次
|
||||
比较都允许跳过大约一半的操作,这样每个查找、插入或删除所花费的时间为
|
||||
树中存储的项目数的对数。 这是比按键在(未排序的)数组中查找元素所需的
|
||||
线性时间要好得多,但比在哈希表中相应的操作慢。
|
||||
|
||||
下图为一个大小为 9,深度为 3,8 为根结点的二叉搜索树。
|
||||
叶子节点没有被绘制。
|
||||
|
||||
![Trie](./images/binary-search-tree.jpg)
|
||||
|
||||
_Made with [okso.app](https://okso.app)_
|
||||
|
||||
## 基础操作的伪代码
|
||||
|
||||
### 插入
|
||||
|
||||
```text
|
||||
insert(value)
|
||||
Pre: value has passed custom type checks for type T
|
||||
Post: value has been placed in the correct location in the tree
|
||||
if root = ø
|
||||
root ← node(value)
|
||||
else
|
||||
insertNode(root, value)
|
||||
end if
|
||||
end insert
|
||||
```
|
||||
|
||||
```text
|
||||
insertNode(current, value)
|
||||
Pre: current is the node to start from
|
||||
Post: value has been placed in the correct location in the tree
|
||||
if value < current.value
|
||||
if current.left = ø
|
||||
current.left ← node(value)
|
||||
else
|
||||
InsertNode(current.left, value)
|
||||
end if
|
||||
else
|
||||
if current.right = ø
|
||||
current.right ← node(value)
|
||||
else
|
||||
InsertNode(current.right, value)
|
||||
end if
|
||||
end if
|
||||
end insertNode
|
||||
```
|
||||
|
||||
### 查找
|
||||
|
||||
```text
|
||||
contains(root, value)
|
||||
Pre: root is the root node of the tree, value is what we would like to locate
|
||||
Post: value is either located or not
|
||||
if root = ø
|
||||
return false
|
||||
end if
|
||||
if root.value = value
|
||||
return true
|
||||
else if value < root.value
|
||||
return contains(root.left, value)
|
||||
else
|
||||
return contains(root.right, value)
|
||||
end if
|
||||
end contains
|
||||
```
|
||||
|
||||
### 删除
|
||||
|
||||
```text
|
||||
remove(value)
|
||||
Pre: value is the value of the node to remove, root is the node of the BST
|
||||
count is the number of items in the BST
|
||||
Post: node with value is removed if found in which case yields true, otherwise false
|
||||
nodeToRemove ← findNode(value)
|
||||
if nodeToRemove = ø
|
||||
return false
|
||||
end if
|
||||
parent ← findParent(value)
|
||||
if count = 1
|
||||
root ← ø
|
||||
else if nodeToRemove.left = ø and nodeToRemove.right = ø
|
||||
if nodeToRemove.value < parent.value
|
||||
parent.left ← nodeToRemove.right
|
||||
else
|
||||
parent.right ← nodeToRemove.right
|
||||
end if
|
||||
else if nodeToRemove.left != ø and nodeToRemove.right != ø
|
||||
next ← nodeToRemove.right
|
||||
while next.left != ø
|
||||
next ← next.left
|
||||
end while
|
||||
if next != nodeToRemove.right
|
||||
remove(next.value)
|
||||
nodeToRemove.value ← next.value
|
||||
else
|
||||
nodeToRemove.value ← next.value
|
||||
nodeToRemove.right ← nodeToRemove.right.right
|
||||
end if
|
||||
else
|
||||
if nodeToRemove.left = ø
|
||||
next ← nodeToRemove.right
|
||||
else
|
||||
next ← nodeToRemove.left
|
||||
end if
|
||||
if root = nodeToRemove
|
||||
root = next
|
||||
else if parent.left = nodeToRemove
|
||||
parent.left = next
|
||||
else if parent.right = nodeToRemove
|
||||
parent.right = next
|
||||
end if
|
||||
end if
|
||||
count ← count - 1
|
||||
return true
|
||||
end remove
|
||||
```
|
||||
|
||||
### 查找某个节点的父节点
|
||||
|
||||
```text
|
||||
findParent(value, root)
|
||||
Pre: value is the value of the node we want to find the parent of
|
||||
root is the root node of the BST and is != ø
|
||||
Post: a reference to the prent node of value if found; otherwise ø
|
||||
if value = root.value
|
||||
return ø
|
||||
end if
|
||||
if value < root.value
|
||||
if root.left = ø
|
||||
return ø
|
||||
else if root.left.value = value
|
||||
return root
|
||||
else
|
||||
return findParent(value, root.left)
|
||||
end if
|
||||
else
|
||||
if root.right = ø
|
||||
return ø
|
||||
else if root.right.value = value
|
||||
return root
|
||||
else
|
||||
return findParent(value, root.right)
|
||||
end if
|
||||
end if
|
||||
end findParent
|
||||
```
|
||||
|
||||
### 查找节点
|
||||
|
||||
```text
|
||||
findNode(root, value)
|
||||
Pre: value is the value of the node we want to find the parent of
|
||||
root is the root node of the BST
|
||||
Post: a reference to the node of value if found; otherwise ø
|
||||
if root = ø
|
||||
return ø
|
||||
end if
|
||||
if root.value = value
|
||||
return root
|
||||
else if value < root.value
|
||||
return findNode(root.left, value)
|
||||
else
|
||||
return findNode(root.right, value)
|
||||
end if
|
||||
end findNode
|
||||
```
|
||||
|
||||
### 查找最小值
|
||||
|
||||
```text
|
||||
findMin(root)
|
||||
Pre: root is the root node of the BST
|
||||
root = ø
|
||||
Post: the smallest value in the BST is located
|
||||
if root.left = ø
|
||||
return root.value
|
||||
end if
|
||||
findMin(root.left)
|
||||
end findMin
|
||||
```
|
||||
|
||||
### 查找最大值
|
||||
|
||||
```text
|
||||
findMax(root)
|
||||
Pre: root is the root node of the BST
|
||||
root = ø
|
||||
Post: the largest value in the BST is located
|
||||
if root.right = ø
|
||||
return root.value
|
||||
end if
|
||||
findMax(root.right)
|
||||
end findMax
|
||||
```
|
||||
|
||||
### 遍历
|
||||
|
||||
#### 中序遍历
|
||||
|
||||
```text
|
||||
inorder(root)
|
||||
Pre: root is the root node of the BST
|
||||
Post: the nodes in the BST have been visited in inorder
|
||||
if root != ø
|
||||
inorder(root.left)
|
||||
yield root.value
|
||||
inorder(root.right)
|
||||
end if
|
||||
end inorder
|
||||
```
|
||||
|
||||
#### 前序遍历
|
||||
|
||||
```text
|
||||
preorder(root)
|
||||
Pre: root is the root node of the BST
|
||||
Post: the nodes in the BST have been visited in preorder
|
||||
if root != ø
|
||||
yield root.value
|
||||
preorder(root.left)
|
||||
preorder(root.right)
|
||||
end if
|
||||
end preorder
|
||||
```
|
||||
|
||||
#### 后序遍历
|
||||
|
||||
```text
|
||||
postorder(root)
|
||||
Pre: root is the root node of the BST
|
||||
Post: the nodes in the BST have been visited in postorder
|
||||
if root != ø
|
||||
postorder(root.left)
|
||||
postorder(root.right)
|
||||
yield root.value
|
||||
end if
|
||||
end postorder
|
||||
```
|
||||
|
||||
## 复杂度
|
||||
|
||||
### 时间复杂度
|
||||
|
||||
| Access | Search | Insertion | Deletion |
|
||||
| :-------: | :-------: | :-------: | :-------: |
|
||||
| O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) |
|
||||
|
||||
### 空间复杂度
|
||||
|
||||
O(n)
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [Wikipedia](https://en.wikipedia.org/wiki/Binary_search_tree)
|
||||
- [Inserting to BST on YouTube](https://www.youtube.com/watch?v=wcIRPqTR3Kc&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=9&t=0s)
|
||||
- [BST Interactive Visualisations](https://www.cs.usfca.edu/~galles/visualization/BST.html)
|
Loading…
Reference in New Issue
Block a user