Go Data Structures: Binary Search Tree
In this article, we will analyze and implement the Binary Search Tree data structure in Go. A Binary Search Tree is a hierarchical data structure where each node can have a maximum of two children. The left child of a node always has a value less than the value of the right child. This data structure is useful for efficient storing, indexing, and retrieval of data.
Terminology
Before diving into the implementation details, let’s go over some terminology related to Binary Search Trees:
- Root: the topmost node of the tree (level 0)
- Child: any node in the tree that is not the root
- Internal node: any node with at least one child
- Leaf: any node that has no children
- Subtree: a set of nodes with a specific node as its root
Preliminary info
The implementation of a Binary Search Tree in Go will expose the following methods:
Insert(t)
: inserts the data itemt
into the treeSearch(t)
: returns true if the data itemt
exists in the treeInOrderTraverse()
: visits all nodes in the tree using in-order traversalPreOrderTraverse()
: visits all nodes in the tree using pre-order traversalPostOrderTraverse()
: visits all nodes in the tree using post-order traversalMin()
: returns the data item with the minimum value stored in the treeMax()
: returns the data item with the maximum value stored in the treeRemove(t)
: removes the data itemt
from the treeString()
: prints a CLI-readable representation of the tree
To create a generic type-safe Binary Search Tree implementation, we will use genny
, a tool that allows us to generate type-specific code. The implementation will use the Item
type, which is a placeholder for the actual type of data to be stored.
Implementation details
The implementation of the Binary Search Tree includes the Node
struct and the ItemBinarySearchTree
struct.
The Node
struct represents a single node in the tree and contains the key (integer) and value (generic type) of the node, as well as the left and right child nodes.
The ItemBinarySearchTree
struct represents the Binary Search Tree itself and contains a reference to the root node. It also includes a read-write mutex to ensure thread-safe access to the tree.
The Insert
method is used to insert a new item into the tree. It uses recursion to find the correct place for the new node. If the key of the new node is less than the key of the current node, it recursively goes left; otherwise, it goes right. If there is no left or right child, the new node is inserted there.
The InOrderTraverse
, PreOrderTraverse
, and PostOrderTraverse
methods traverse the tree in three different ways using recursion. In-order traversal visits nodes in ascending order of the key value, pre-order traversal visits the node before its children, and post-order traversal visits the node after its children.
The Min
and Max
methods return the data item with the minimum and maximum values in the tree, respectively. They traverse the tree to find the leftmost and rightmost nodes.
The Search
method searches for a specific key in the tree using recursion. If the key is less than the current node’s key, it recursively searches the left subtree; if the key is greater, it searches the right subtree. If the key is found, it returns true; otherwise, it returns false.
The Remove
method removes a node with a specific key from the tree. It uses recursion to find the node to be removed and handles different cases based on the number of children the node has.
The String
method prints a CLI-readable representation of the tree. It uses recursion to traverse the tree and format the output accordingly.
Testing
The provided tests demonstrate the usage of the Binary Search Tree implementation. They cover the insertion of nodes, traversal methods, finding the minimum and maximum values, searching for specific keys, and removing nodes from the tree.
Creating a concrete tree data structure
You can use the generic implementation provided to generate type-specific Binary Search Trees. To create a Binary Search Tree of int
values, run the following command:
1 | genny -in binarysearchtree.go -out binarysearchtree-int.go gen "Item=int" |
To create a Binary Search Tree of string
values, run the following command:
1 | genny -in binarysearchtree.go -out binarysearchtree-string.go gen "Item=string" |
(Tag: data structures, programming, Go, Binary Search Tree)