Chapter 20
Binary Search Trees
20.1 Binary Search Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
20.2 Inserting Data into a Binary Search Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
20.3 Searching a Binary Search Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
20.4 Printing a Binary Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
20.5 Deleting from a Binary Search Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
20.6 Destroying a Binary Search Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
20.7 main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
20.8 Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
20.9 Counting the Different Shapes of a Binary Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
The previous chapter explained linked lists. Each Node has precisely one link called next.
Traversing the list to find a given node means starting at the first node—usually called the
head—and visiting each node in turn. In a doubly linked list, each Node has two links (next
and previous). A doubly linked list allows for traversing forward using next and backward
using previous. Even though doubly linked lists are more convenient, they still have the
same limitations of singly linked lists. If the list is long, then finding particular nodes may
require visiting many nodes. If we want to efficiently add and remove data, a linked list is
insufficient.
Section 15.1 provides an example of quickly locating data in an array by skipping large
portions of it. This is a step in the right direction. Note, however, that the array must be
sorted before a binary search can be applied. Furthermore, the array’s size is fixed. Inserting
an element in an array can be expensive, because there may not be enough memory available.
It is necessary to allocate a new array and copying data before freeing the old array. If the
new element is inserted at the beginning, all the elements must be moved. This is inefficient.
Can a dynamic structure support the efficient searching properties of binary searching,
but still preserve the ability to quickly add and remove elements? Binary search trees are
designed to do precisely that. A binary search tree can typically discard half of the data in
a single comparison. This makes search efficient. A binary search tree is one type of binary
tree. A binary search tree is always a binary tree, but a binary tree may not necessarily
be a binary search tree. We will start exploring binary search trees and then generalize to
binary trees.
Like a linked list, a binary search tree is composed of nodes that are linked together.
The tree is a single root node similar to the head node in a linked list. Every node in a
binary tree has two links called left and right. A binary tree is different from a doubly
linked list. In a doubly linked list, if p -> next is q, then q -> previous must be p. It is
possible to reach p from q and it is also possible to reach q from p. Even though each node
has two links, they form a single chain.
The situation is fundamentally different in binary trees. Although each node has two
links, the links point to distinct nodes. This means that if q is p -> left or p -> right,
neither q -> left nor q -> right is p. It is possible to reach q from p but it is impossible
to reach p from q.
317