Trees


Overview of Trees

A tree is a non-linear data structure. Data access and storage in trees is faster than with linear data structures such as linked lists and trees are a more natural fit for many types of data. For example, the tree below represents my web site.

trees 1

Terminology

Ordered Trees

Ordered trees maintain a linear relationship between the nodes in the tree. A binary tree is a tree in which each node has at maximum two children. A binary search tree is an ordered binary tree. Below is an example of a binary search tree.

BST 1:

trees 2

BST 2:

The following tree contains the same node and is also a binary search tree.

trees 3

Tree Traversal

Pre and post order tree traversal algorithms visit every node in a given tree in a particular order. Both are recursive algorithms that begin with the root of the tree. A pre-order traversal visits a node and then recursively visits its left child and right child. A post-order traversal visits a node's left child, a node's right child, then the node itself. The algorithms are shown below:

preOrder(node) postOrder(node)
if(node != null) {

    node.visit()

    preOrder(node.leftChild())

    preOrder(node.rightChild())

}

if(node != null) {

    postOrder(node.leftChild())

    postOrder(node.rightChild())

    node.visit()

}

The result of a pre-order traversal on BST1 above would yield the following result:

Rollins, Davidson, Brown, Ralson, Truman, Taft, Zuniga

The result of a post-order traversal on BST1 above would yield the following result:

Brown, Ralson, Davidson, Taft, Zuniga, Truman, Rollins

What would be the result of a pre/post order traversal on BST2?

An in-order traversal visits a node's left child, visits the node, then visits the node's right child. In a BST, this yields an ordered traversal of the elements stored in the tree.

Implementation

Each node in a BST is similar to a linked list node. A BSTNode contains a data object, a reference to the left subtree, and a reference to the right subtree.

trees4

A BinarySeachTree class may contain the following methods:

find

The find method takes as input a target element and returns true if the element exists in the tree and false if it does not. The algorithm for find is as follows:

find(target, currentNode)
        if currentNode != null 
                if target == currentNode.data
                        return true
                if target < currentNode.data
                        return find(target, currentNode.left)
                return find(target, currentNode.right)

insert

The insert method takes as input a new element and inserts it into the correct location in the tree. The algorithm for insert is as follows:

insert(data, currentNode)
        if data < currentNode.data && currentNode.left == null
                currentNode.left = new Node(data)
        if data > currentNode.data && currentNode.right == null
                currentNode.right = new Node(data)
        if data < currentNode
                insert(data, currentNode.left)
        else
                insert(data, currentNode.right)

Note that the algorithm above does not consider special cases.

remove

The remove method takes as input the element to be removed and removes it from the tree. Following is a sketch of the algorithm for the remove method:

remove(target)
	find node containing target
	if node has no children
		set parent's reference to node to null
	if node has only a right child
		replace node with its right child
	if node has only a left child
		replace node with its left child
	if node has two children
		replace node with predecessor (or sucecessor)
		recursively remove predecessor (or successor)

Sami Rollins

Date: 2007-11-05