Skip to content

Commit 6e4ab26

Browse files
author
user
committed
Update readme.md and remove some platforms from the GitHub workflow.
1 parent 7ae19c2 commit 6e4ab26

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

.github/workflows/rust.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ jobs:
1919
matrix:
2020
os: [
2121
ubuntu-latest, ubuntu-24.04, ubuntu-22.04, ubuntu-24.04-arm, ubuntu-22.04-arm,
22-
macos-latest, macos-14, macos-15, macos-26, macos-13, macos-15-intel
23-
windows-latest, windows-2025, windows-2022, windows-11-arm,
22+
macos-latest, macos-14, macos-15, macos-26, macos-13
23+
windows-2025, windows-2022, windows-11-arm,
2424
]
2525
runs-on: ${{ matrix.os }}
2626

readme.md

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,40 @@ When implementing an AVL tree, there are some choices:
66
* Storing the balance factor or height in a node.
77
* Taking a recursive or iterative approach.
88

9-
This is a recursive implementation of an AVL tree that stores the height in a node and does not store the parent pointer in it. Key points:
9+
This is a recursive implementation of an AVL tree that stores the height in a node
10+
and does not store the parent pointer in it. Key points:
1011
* Written in pure Rust.
11-
* No unsafe code (other than [the mutable iterator](src/avl.rs#L544)).
12-
* The key data type can be any type that has Ord.
12+
* No `unsafe` code (other than the [mutable iterator](src/avl.rs#L544)).
13+
* The key type can be any type that has `Ord`.
1314
* Each node is identified by a key, and so there are no nodes with the same key.
1415

15-
[The iterative implementation](/../iterative)
16-
is slightly faster, but uses more unsafe code and is more complex because it requires tracing the path of ancestor nodes during tree modification.
17-
1816
## Description
1917
<picture>
2018
<source media="(prefers-color-scheme: dark)" srcset="img/AVLTreeDarkTheme.png">
2119
<source media="(prefers-color-scheme: light)" srcset="img/AVLTreeLightTheme.png">
22-
<img src="img/AVLTreeDarkTheme.png" width="650">
20+
<img src="img/AVLTreeDarkTheme.png" width="620">
2321
</picture>
2422

2523
**A diagram of an AVL tree with a balance factor labeled below each node.**
2624

27-
2825
The AVL tree, named after its inventors, is a self-balancing binary search tree (BST)
2926
that has a worst-case time complexity of $O(log(n))$ on lookup, insertion, and deletion.
3027

3128
An ordinary (unbalanced) BST has a worst-case time complexity of $O(n)$ for the basic operations.
32-
Without rebalancing, the tree height keeps increasing on insertion, and the performance degrades to that of a linked list, that is, linear time.
29+
Without rebalancing, the tree height keeps increasing on insertion,
30+
and the performance degrades to that of a linked list, that is, linear time.
3331

3432
Therefore, rebalancing through tree rotations is necessary to keep the useful property of BSTs.
3533

36-
Here is
37-
[an interactive tool to visualize how AVL trees work](https://www.cs.usfca.edu/~galles/visualization/AVLtree.html).
38-
39-
## License
40-
All code, including the test module, is released under the MIT license.
41-
42-
The diagram above is my own work and is released into the public domain (CC0).
34+
Here is an
35+
[interactive tool to visualize how AVL trees work](https://www.cs.usfca.edu/~galles/visualization/AVLtree.html).
4336

4437
## Definitions
4538
Below I provide the definitions used throughout this repository.
4639

4740
### Depth
48-
The depth of a node is the depth of its parent plus one. An empty node's depth is zero. A root node has no parent, thus its depth is $0 + 1 = 1$.[^1]
41+
The depth of a node is the depth of its parent plus one. An empty node's depth is zero.
42+
A root node has no parent, thus its depth is $0 + 1 = 1$.[^1]
4943

5044
### Height
5145
The height of a node $X$ is the maximum of the heights of its children plus one:
@@ -75,3 +69,24 @@ In the diagram above, the root node $R$ is left-heavy, since $BF(R) = Height(S)
7569
[^1]: This differs from the usual definition, where a root's depth is zero.
7670
[^2]: This differs from the usual definition, where a leaf's height is zero.
7771
[^3]: In the usual definition, it's three.
72+
73+
## Implementation notes
74+
The [iterative implementation](../iterative) is slightly faster, but uses `unsafe` code
75+
and is more complex because it requires tracing the path of ancestor nodes during tree modification.
76+
77+
All primitive integer types have `Ord`, so they can be used as the key type. So does `String`, since it has `Ord`.
78+
79+
IEEE 754 floating-point arithmetic has a special value called "Not a Number" (NaN),
80+
which is not equal to anything, not even to itself.
81+
Because NaN violates the [trichotomy](https://en.wikipedia.org/wiki/Law_of_trichotomy),
82+
floating-point types like `f32` cannot have `Ord`, so they cannot be used as the key type.
83+
84+
A key-value pair is stored in the node itself.
85+
During a tree rotation, everything of the node is swapped with another (using `std::mem::swap`).
86+
Therefore, if the key or value were large, expensive memory copies might take place during insertion or deletion.
87+
88+
## License
89+
All code, including the [test module](src/avl_test.rs), is released under the MIT license.
90+
91+
The diagram above is my own work and is released into the public domain
92+
([CC0](https://creativecommons.org/publicdomain/zero/1.0/)).

0 commit comments

Comments
 (0)