Introduction

In this tutorial, we’ll talk about a binary search tree data structure time complexity.

2. The Main Property of a Binary Tree

Knuth defines binary trees as follows: “A binary tree is a finite set of nodes which either is empty or consists of a root and two disjoint binary trees called the left and the right subtrees of the root.”

Let’s start with a generic structure of a binary tree:

Binary Tree 1

There are, of course, non-binary trees. However, it is important to note that a binary tree is not a special case of a tree but is a different concept. For example, those trees:

Binary Tree 2

We can consider them identical when defining them as ordinary trees but different when analyzed as binary trees.

In a binary search tree, each node is identified by a key, which is stored respecting the following property:Let \boldsymbol{x} be a node of a binary tree. If \boldsymbol{y} is a node in the left subtree of \boldsymbol{x} then \boldsymbol{key[y] \le key[x]} . If \boldsymbol{y} is a node in the right subtree of \boldsymbol{x}, then \boldsymbol{key[y] \ge  key[x]}.

Elementary Operations in Binary Search Trees

Suppose a set of data, for example, a database D, which contains information in ASCII format. Each row or record in the database is made up of a series of distinct fields identified by a key. Let n be the number of records in the database, each consisting of N fields.

We’ll then have a key field and N-1 fields containing the associated information. Suppose that the key is unique for each record. It is possible to store D organized as a binary search tree based on the property mentioned above.

Elementary or primitive operations in the binary search trees are search, minimum, maximum, predecessor, successor, insert, and delete. Computational complexity depends on the concept of the height of the tree h, which we can informally define as the number of levels of which the tree is composed. For example, the binary tree from the first figure has 5 levels (including root).

4. Time Complexity of a Search in a Binary Tree

Suppose we have a key k, and we want to retrieve the associated fields of D for k. The problem is formulated as the identification of the node x such that key[x] =k. So, we move into the tree, starting from the root node, comparing our key with the keys of the nodes we visit. Note that each move involves the descent of a level in the tree.

If the key is unique, the number of nodes visited during the search is at most equal to h, and the search can be done in time O(h). This behavior is also satisfied by the other primitive operations, so we have the following important and intuitive result: all operations in Binary Search Tree of height \boldsymbol{h} can be performed in time \boldsymbol{O(h)}.

Not all binary search trees are equally efficient when performing a primitive operation. The key to improving efficiency is given by the fact that computational complexity depends on h and not on n.

The way the elements are arranged in the binary tree affects its height. In general, we can state the problem of the optimal construction, such as the search for the arrangement of the nodes that leads to the tree with the minimum height.

The worst scenario is a database D already sorted by key. In this case, if we build a binary tree through insertions of the n records in the original order, we will get a tree that contains only left or right subtrees, depending on whether the order of the keys is respectively descending or ascending:

Binary Tree 3

In this case, h=n, and by the discussion of the previous paragraph, the realization of a primitive operation occurs in time O(n). This case is equivalent to a linked list.

6. Search in Balanced Trees

If keys of D are disordered, building a binary tree based on insert operations produces a structure with h<n. When the heights of the left and right subtree of any node differ by not more than 1, the tree is said to be balanced, and the following result can be demonstrated:

The average height of a randomly constructed binary search tree with \boldsymbol{n} distinct keys is \boldsymbol{O(log{_2}n)}.

From previous results, we conclude that the search for a key and, in general, any primitive operation performed on a binary search tree, takes time O(n) in the worst case and O(log{_2}n) in the average case. The construction of a tree based on the insertion of the n records of D therefore requires time O(n^2) in the worst case and O(nlog{_2}n) in the average case.

7. Practical Problems and Variants in Binary Search Trees

Binary search trees are used in many computational procedures. However, the basic theory illustrated in this tutorial is not without problems.

In real applications, binary search trees are not necessarily balanced. It must be considered that maintaining a perfectly balanced binary tree at each step is an expensive procedure, which could lead to a removal of the balancing conditions and overall degradation.

There are variants that solve these drawbacks. Examples are self-balancing binary search trees and RB-trees (Red-Black).

RB-trees are used within many database engines. Compared to standard binary trees, they also contain an additional binary field called color. Through precise rules of coloring the nodes, it can be obtained that the length of any path is not more than twice as any other.

All these variants of the binary trees are designed pursuing the same objective: the optimal construction that allows obtaining an optimal balancing that results in a tree of minimum height.

8. Conclusions

In this tutorial, we have made an overview of the basic theory of binary search trees. We have focused on the computational cost of primitive operations, in particular the search operation.

In the text, some ideas are suggested to the reader for further study, in particular the possible balancing techniques.

Comments are closed on this article!