Close
Close Window

MHC S25 COMSC 205: Data Structures

Chapter 16 Binary Trees

«  15.1. Binary Trees   ::   Contents   ::   16.2. Binary Tree Traversals  »

16.1. Binary Tree Implementation

16.1.1. Nodes in a Binary Tree

Much like how we implemented linked lists, we define a BinaryTreeNode class to represent a node in a binary tree.

//Represents a node in a binary tree as a recursive data structure.
public class BinaryTreeNode<T> {
    private T value;
    private BinaryTreeNode<T> left;
    private BinaryTreeNode<T> right;

    public BinaryTreeNode(T value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
    
    public T getValue() {
        return this.value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public BinaryTreeNode<T> getLeft() {
        return this.left;
    }

    public BinaryTreeNode<T> getRight() {
        return this.right;
    }

    public void setLeft(BinaryTreeNode<T> left) {
        this.left = left;
    }

    public void setRight(BinaryTreeNode<T> right) { 
        this.right = right;
    }

    // Checks if the node is a leaf node, which means it has no children.
    public boolean isLeaf() {
        return this.left == null && this.right == null;
    }
}   

Like our previous node classes, this class has a value instance variable to store the value of the node. Now, we store pointers to the node’s left and right children in left and right instance variables.

There are also the usual getters and setters for the value and left and right instance variables. The one method additional method to note here is isLeaf(), which returns true if the node is a leaf node (i.e. it has no children) and false otherwise:

    // Checks if the node is a leaf node, which means it has no children.
    public boolean isLeaf() {
        return this.left == null && this.right == null;
    }

16.1.2. BinaryTree class

Carrying over the same idea of our linked list implementations holding a head and tail pointer, our binary tree implementation will hold a root pointer. The root pointer will point to the root node of the binary tree. Below is a partial implementation of the BinaryTree class:

public class BinaryTree<T> {
    private BinaryTreeNode<T> root;

    public BinaryTree() {
        this.root = null;
    }
    public BinaryTreeNode<T> getRoot() {
        return this.root;
    }

    public void setRoot(BinaryTreeNode<T> root) {
        this.root = root;
    }

    public int size() {
        return this.size(this.root);
    }

    private int size(BinaryTreeNode<T> node) {
        if (node == null) {
            return 0;
        }

        return 1 + this.size(node.getLeft()) + this.size(node.getRight());
    }

    public int height() {
        return this.height(this.root);
    }

    private int height(BinaryTreeNode<T> node) {
        // base case: empty node has height 0
        if (node == null) {
            return 0;
        }

        // recursive case: height is 1 (for the current node),
        // plus the height of the taller subtree
        int leftHeight = this.height(node.getLeft());
        int rightHeight = this.height(node.getRight());
        
        if (leftHeight > rightHeight) {
            return 1 + leftHeight;
        } else {
            return 1 + rightHeight;
        }
    }

    public boolean isEmpty() {
        return this.root == null;
    }
}

Note

Notice that the size() and height() methods are defined recursively. We’ll go over their implementations during lecture!

16.1.3. Recursively implementing height()

Settings

Proficient Saving... Error Saving
Server Error
Resubmit

   «  15.1. Binary Trees   ::   Contents   ::   16.2. Binary Tree Traversals  »

Close Window