Abstract
For more than two decades, functional programmers have refined the persistent red-black tree—a data structure of unrivaled elegance. This paper presents another step in its evolution. Using a monad to communicate balancing information yields a fast insertion procedure, without sacrificing clarity. Employing the same monad plus a new decomposition simplifies the deletion procedure, without sacrificing efficiency.
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Similar content being viewed by others
Notes
- 1.
The diagrams use the letters x, y, z for values; the letters a, b, c, d for subtrees; and \(\bullet \) for the empty tree.
- 2.
Where bh computes the black height of a tree.
- 3.
This type is the same as Either, but with more convenient constructors.
- 4.
Note that \(\mathtt {<}\)$$\(\mathtt {>}\) is not fmap. The functor instance implied by the monad applies a function only to T values.
- 5.
The half-colored nodes indicate that the color could be either red or black.
- 6.
Some split balance into balanceL and balanceR [10, exercise 3.10]. For balance, splitting is done for performance rather than convenience.
- 7.
The dotted triangle encloses the tree that balance’ is applied to.
References
Appel, A.: Efficient verified red-black trees (2011). https://www.cs.princeton.edu/~appel/papers/redblack.pdf
Ashley, J.M., Dybvig, R.K.: An efficient implementation of multiple return values in scheme. In: LISP and Functional Programming (LFP) (1994). https://doi.org/10.1145/182590.156784
Cormen, T., Leiserson, C., Rivest, R., Stein, C.: Introduction to Algorithms. MIT Press (2009)
Filliâtre, J.-C., Letouzey, P.: Functors for proofs and programs. In: Schmidt, D. (ed.) ESOP 2004. LNCS, vol. 2986, pp. 370–384. Springer, Heidelberg (2004). https://doi.org/10.1007/978-3-540-24725-8_26
Flatt, M., PLT: reference: racket. Technical report. PLT-TR-2010-1, PLT Design Inc. (2010). https://racket-lang.org/tr1/
Germane, K., Might, M.: Deletion: the curse of the red-black tree. J. Funct. Program. (JFP) (2014). https://doi.org/10.1017/S0956796814000227
Greenman, B., et al.: How to evaluate the performance of gradual typing systems. J. Funct. Program. (JFP) (2019). https://doi.org/10.1017/S0956796818000217
Guibas, L., Sedgewick, R.: A dichromatic framework for balanced trees. In: IEEE Symposium on Foundations of Computer Science (1978). https://doi.org/10.1109/SFCS.1978.3
Kahrs, S.: Red-black trees with types. J. Funct. Program. (JFP) (2001). https://doi.org/10.1017/S0956796801004026
Okasaki, C.: Purely Functional Data Structures. Cambridge University Press (1999)
Okasaki, C.: Red-black trees in a functional setting. J. Funct. Program. (JFP) (1999). https://doi.org/10.1017/S0956796899003494
Peyton Jones, S.: Haskell 98 Language and Libraries: The Revised Report. Cambridge University Press (2003)
Weirich, S.: Red black trees (redux) (2021). https://www.seas.upenn.edu/~cis5520/21fa/lectures/stub/06-GADTs/RedBlackGADT0.html
Acknowledgements
Thanks to Matthias Felleisen for his feedback and encouragement. Also, thanks to Ben Lerner, Jason Hemann, Leif Andersen, Michael Ballantyne, Mitch Gamburg, Sam Caldwell, audience members at TFP, and anonymous TFP reviewers for providing valuable comments that significantly improved the exposition.
Much of the code in this paper was directly adapted or at least heavily influenced by the code of Okasaki [11] (for insertion) and Germane and Might [6] (for deletion). They deserve a great deal of credit for the final product.
This work was partially supported by NSF grant SHF 2116372.
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
Appendices
A Racket Implementation
This section shows a Racket port of the Haskell code. Monads can be implemented in many ways, but the following code uses macros and multiple return values [2] to do so. This choice yields excellent performance.
B Performance Evaluation Correction
Germane and Might [6] incorrectly conclude that their algorithm is always significantly slower than other approaches. This conclusion is due to a subtle confounding factor that put their algorithm at an unfair disadvantage.
To understand the flaw, consider this skeleton of their delete function:
It highlights the two most common cases during deletion, when the current node does not match the target and the function recurs on either the left or right side. However, the structure of the code forces each of the base cases to be checked first—before the most common cases.
To favor the common cases, the skeleton should look as follows:
The base cases are only checked at the target node. This simple modification improves the performance of the double-black algorithm by \(2 \times \).
Rights and permissions
Copyright information
© 2023 The Author(s), under exclusive license to Springer Nature Switzerland AG
About this paper
Cite this paper
Moy, C. (2023). Faster, Simpler Red-Black Trees. In: Chang, S. (eds) Trends in Functional Programming. TFP 2023. Lecture Notes in Computer Science, vol 13868. Springer, Cham. https://doi.org/10.1007/978-3-031-38938-2_3
Download citation
DOI: https://doi.org/10.1007/978-3-031-38938-2_3
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-031-38937-5
Online ISBN: 978-3-031-38938-2
eBook Packages: Computer ScienceComputer Science (R0)