7.1: Random Binary Search Trees
- Page ID
- 8465
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Consider the two binary search trees shown in Figure \(\PageIndex{1}\), each of which has \(\mathtt{n}=15\) nodes. The one on the left is a list and the other is a perfectly balanced binary search tree. The one on the left has a height of \(\mathtt{n}-1=14\) and the one on the right has a height of three.
Imagine how these two trees could have been constructed. The one on the left occurs if we start with an empty BinarySearchTree and add the sequence
\[ \langle 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 \rangle \enspace . \nonumber\]
No other sequence of additions will create this tree (as you can prove by induction on \(\mathtt{n}\)). On the other hand, the tree on the right can be created by the sequence
\[ \langle 7,3,11,1,5,9,13,0,2,4,6,8,10,12,14 \rangle \enspace . \nonumber\]
Other sequences work as well, including
\[ \langle 7,3,1,5,0,2,4,6,11,9,13,8,10,12,14 \rangle \enspace , \nonumber\]
and
\[ \langle 7,3,1,11,5,0,2,4,6,9,13,8,10,12,14 \rangle \enspace . \nonumber\]
In fact, there are \(21,964,800\) addition sequences that generate the tree on the right and only one that generates the tree on the left.
The above example gives some anecdotal evidence that, if we choose a random permutation of \(0,\ldots,14\), and add it into a binary search tree, then we are more likely to get a very balanced tree (the right side of Figure \(\PageIndex{1}\)) than we are to get a very unbalanced tree (the left side of Figure \(\PageIndex{1}\)).
We can formalize this notion by studying random binary search trees. A random binary search tree of size \(\mathtt{n}\) is obtained in the following way: Take a random permutation, \(\mathtt{x}_0,\ldots,\mathtt{x}_{\mathtt{n}-1}\), of the integers \(0,\ldots,\mathtt{n}-1\) and add its elements, one by one, into a BinarySearchTree. By random permutation we mean that each of the possible \(\mathtt{n}!\) permutations (orderings) of \(0,\ldots,\mathtt{n}-1\) is equally likely, so that the probability of obtaining any particular permutation is \(1/\mathtt{n}!\).
Note that the values \(0,\ldots,\mathtt{n}-1\) could be replaced by any ordered set of \(\mathtt{n}\) elements without changing any of the properties of the random binary search tree. The element \(\mathtt{x}\in\{0,\ldots,\mathtt{n}-1\}\) is simply standing in for the element of rank \(\mathtt{x}\) in an ordered set of size \(\mathtt{n}\).
Before we can present our main result about random binary search trees, we must take some time for a short digression to discuss a type of number that comes up frequently when studying randomized structures. For a non-negative integer, \(k\), the \(k\)-th harmonic number, denoted \(H_k\), is defined as
\[ H_k = 1 + 1/2 + 1/3 + \cdots + 1/k \enspace . \nonumber\]
The harmonic number \(H_k\) has no simple closed form, but it is very closely related to the natural logarithm of \(k\). In particular,
\[ \ln k < H_k \le \ln k + 1 \enspace . \nonumber\]
Readers who have studied calculus might notice that this is because the integral \(\int_1^k\! (1/x)\, \mathrm{d}x= \ln k\). Keeping in mind that an integral can be interpreted as the area between a curve and the \(x\)-axis, the value of \(H_k\) can be lower-bounded by the integral \(\int_1^k\! (1/x)\, \mathrm{d}x\) and upper-bounded by \(1+ \int_1^k\! (1/x)\, \mathrm{d}x\). (See Figure \(\PageIndex{2}\) for a graphical explanation.)
In a random binary search tree of size \(\mathtt{n}\), the following statements hold:
- For any \(\mathtt{x}\in\{0,\ldots,\mathtt{n}-1\}\), the expected length of the search path for \(\mathtt{x}\) is \(H_{\mathtt{x}+1} + H_{\mathtt{n}-\mathtt{x}} - O(1)\).1
- For any \(\mathtt{x}\in(-1,n)\setminus\{0,\ldots,\mathtt{n}-1\}\), the expected length of the search path for \(\mathtt{x}\) is \(H_{\lceil\mathtt{x}\rceil} + H_{\mathtt{n}-\lceil\mathtt{x}\rceil}\).
We will prove Lemma \(\PageIndex{1}\) in the next section. For now, consider what the two parts of Lemma \(\PageIndex{1}\) tell us. The first part tells us that if we search for an element in a tree of size \(\mathtt{n}\), then the expected length of the search path is at most \(2\ln n + O(1)\). The second part tells us the same thing about searching for a value not stored in the tree. When we compare the two parts of the lemma, we see that it is only slightly faster to search for something that is in the tree compared to something that is not.
\(\PageIndex{1}\) Proof of Lemma \(\PageIndex{1}\)
The key observation needed to prove Lemma \(\PageIndex{1}\) is the following: The search path for a value \(\mathtt{x}\) in the open interval \((-1,\mathtt{n})\) in a random binary search tree, \(T\), contains the node with key \(i < \mathtt{x}\) if, and only if, in the random permutation used to create \(T\), \(i\) appears before any of \(\{i+1,i+2,\ldots,\lfloor\mathtt{x}\rfloor\}\).
To see this, refer to Figure \(\PageIndex{3}\) and notice that until some value in \(\{i,i+1,\ldots,\lfloor\mathtt{x}\rfloor\}\) is added, the search paths for each value in the open interval \((i-1,\lfloor\mathtt{x}\rfloor+1)\) are identical. (Remember that for two values to have different search paths, there must be some element in the tree that compares differently with them.) Let \(j\) be the first element in \(\{i,i+1,\ldots,\lfloor\mathtt{x}\rfloor\}\) to appear in the random permutation. Notice that \(j\) is now and will always be on the search path for \(\mathtt{x}\). If \(j\neq i\) then the node \(\mathtt{u}_j\) containing \(j\) is created before the node \(\mathtt{u}_i\) that contains \(i\). Later, when \(i\) is added, it will be added to the subtree rooted at \(\mathtt{u}_j\texttt{.left}\), since \(i<j\). On the other hand, the search path for \(\mathtt{x}\) will never visit this subtree because it will proceed to \(\mathtt{u}_j\texttt{.right}\) after visiting \(\mathtt{u}_j\).
Similarly, for \(i>\mathtt{x}\), \(i\) appears in the search path for \(\mathtt{x}\) if and only if \(i\) appears before any of \(\{\lceil\mathtt{x}\rceil, \lceil\mathtt{x}\rceil+1,\ldots,i-1\}\) in the random permutation used to create \(T\).
Notice that, if we start with a random permutation of \(\{0,\ldots,\mathtt{n}\}\), then the subsequences containing only \(\{i,i+1,\ldots,\lfloor\mathtt{x}\rfloor\}\) and \(\{\lceil\mathtt{x}\rceil, \lceil\mathtt{x}\rceil+1,\ldots,i-1\}\) are also random permutations of their respective elements. Each element, then, in the subsets \(\{i,i+1,\ldots,\lfloor\mathtt{x}\rfloor\}\) and \(\{\lceil\mathtt{x}\rceil, \lceil\mathtt{x}\rceil+1,\ldots,i-1\}\) is equally likely to appear before any other in its subset in the random permutation used to create \(T\). So we have
\[\Pr\{ \mbox{$i$ is on the search path for $\mathtt{x}$} \} =
\left\{ \begin{array}{ll}
1/(\lfloor\mathtt{x}\rfloor-i+1) & \mbox{if $i < \mathtt{x}$}\\
1 /(i-\lceil \mathtt{x}\rceil +1) & \mbox{if $i > \mathtt{x}$}
\end{array}\right . \enspace .\nonumber\]
With this observation, the proof of Lemma \(\PageIndex{1}\) involves some simple calculations with harmonic numbers:
Proof of Lemma \(\PageIndex{1}\)
Let \(I_i\) be the indicator random variable that is equal to one when \(i\) appears on the search path for \(\mathtt{x}\) and zero otherwise. Then the length of the search path is given by
\[ \sum_{i\in\{0,\ldots,\mathtt{n}-1\}\setminus\{\mathtt{x}\}} I_i \nonumber\]
so, if \(\mathtt{x}\in\{0,\ldots,\mathtt{n}-1\}\), the expected length of the search path is given by (see Figure \(\PageIndex{4}\).a)
\[\begin{align}
\mathrm{E}\left[\sum_{i=0}^{\mathtt{x}-1} I_i + \sum_{i=\mathtt{x}+1}^{\mathtt{n}-1} I_i\right]
&= \sum_{i=0}^{\mathtt{x}-1} \mathrm{E}\left[I_i\right] +\sum_{i= \mathtt{x}+1}^{\mathtt{n}-1} \mathrm{E}\left[I_i\right]\nonumber\\
&= \sum_{i=0}^{\mathtt{x}-1} 1/(\lfloor\mathtt{x}\rfloor-i+1)+\sum_{i=\mathtt{x}+1}^{\mathtt{n}-1} 1/(i-\lceil\mathtt{x}\rceil+1)\nonumber\\
&= \sum_{i=0}^{\mathtt{x}-1} 1/(\mathtt{x}-i+1)+\sum_{i= \mathtt{x}+1}^{\mathtt{n}-1} 1/(i-\mathtt{x}+1)\nonumber\\
&= \frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{\mathtt{x}+1}\nonumber\\
&\quad {} + \frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{\mathtt{n}-\mathtt{x}}\nonumber\\
&= H_{\mathtt{x}+1} + H_{\mathtt{n}-\mathtt{x}} - 2 \enspace .\nonumber\\
\end{align}\nonumber\]
The corresponding calculations for a search value \(\mathtt{x}\in(-1,n)\setminus\{0,\ldots,\mathtt{n}-1\}\) are almost identical (see Figure \(\PageIndex{4}\).b).
(a)
(b)
\(\PageIndex{2}\) Summary
The following theorem summarizes the performance of a random binary search tree:
A random binary search tree can be constructed in \(O(\mathtt{n}\log \mathtt{n})\) time. In a random binary search tree, the \(\mathtt{find(x)}\) operation takes \(O(\log\mathtt{n})\) expected time.
We should emphasize again that the expectation in Theorem \(\PageIndex{1}\) is with respect to the random permutation used to create the random binary search tree. In particular, it does not depend on a random choice of \(\mathtt{x}\); it is true for every value of \(\mathtt{x}\).