JavaScript Frontend Data Structures: Trees

Tree Definiiton and Characteristics

A tree is a data structure with n (n ≥ 0) finite nodes in a hierarchical relationship. Called a "tree" as it resembles an upside - down tree (root up, leaves down). Key traits:

  • A node may have 0+ child nodes.
  • The root node has no parent.
  • Every non - root node has exactly one parent.
  • Except the root, each child node can belong to multiple disjoint subtrees.
  • A binary tree allows at most two subtrees per node.
  • A Binary Search Tree (BST) (also named ordered/sorted binary tree) is a binary tree (or empty) with:
    • If the left subtree is not empty, all left - subtree nodes have values less than the root’s value.
    • If the right subtree is not empty, all right - subtree nodes have values greater than the root’s value.

Code Implementation

Main Class (Binary Search Tree)

class BinaryTree {
  constructor() {
    this.root = null; // Renamed for clarity
  }
}

Node Class (Linked - List - like Structure)

class TreeNode {
  constructor(value) {
    this.value = value; // Renamed from 'key'
    this.leftChild = null; // Renamed from 'left'
    this.rightChild = null; // Renamed from 'right'
  }
}

Inserting Nodes

// Add a node to the tree
BinaryTree.prototype.add = function (value) {
  const newNode = new TreeNode(value);
  if (this.root === null) {
    this.root = newNode;
  } else {
    insertIntoTree(this.root, newNode);
  }
};

function insertIntoTree(currentRoot, newNode) {
  if (newNode.value < currentRoot.value) {
    if (currentRoot.leftChild === null) {
      currentRoot.leftChild = newNode;
    } else {
      insertIntoTree(currentRoot.leftChild, newNode);
    }
  } else {
    if (currentRoot.rightChild === null) {
      currentRoot.rightChild = newNode;
    } else {
      insertIntoTree(currentRoot.rightChild, newNode);
    }
  }
}

Tree Traversal

Three common traversal methods (recursive implementations; iterative versions exist too):

// Pre - order: Root → Left Subtree → Right Subtree
BinaryTree.prototype.preOrderTraverse = function (callback) {
  preOrderHelper(this.root, callback);
};

function preOrderHelper(node, callback) {
  if (node) {
    callback(node.value);
    preOrderHelper(node.leftChild, callback);
    preOrderHelper(node.rightChild, callback);
  }
}

// In - order: Left Subtree → Root → Right Subtree
BinaryTree.prototype.inOrderTraverse = function (callback) {
  inOrderHelper(this.root, callback);
};

function inOrderHelper(node, callback) {
  if (node) {
    inOrderHelper(node.leftChild, callback);
    callback(node.value);
    inOrderHelper(node.rightChild, callback);
  }
}

// Post - order: Left Subtree → Right Subtree → Root
BinaryTree.prototype.postOrderTraverse = function (callback) {
  postOrderHelper(this.root, callback);
};

function postOrderHelper(node, callback) {
  if (node) {
    postOrderHelper(node.leftChild, callback);
    postOrderHelper(node.rightChild, callback);
    callback(node.value);
  }
}

Min/Max Values

To find the leftmost (min) or rightmost (max) node:

// Find minimum value (leftmost node)
BinaryTree.prototype.findMin = function () {
  if (!this.root) return null;
  return getMinNode(this.root).value;
};

// Find maximum value (rightmost node)
BinaryTree.prototype.findMax = function () {
  if (!this.root) return null;
  return getMaxNode(this.root).value;
};

function getMinNode(node) {
  while (node && node.leftChild) {
    node = node.leftChild;
  }
  return node;
}

function getMaxNode(node) {
  while (node && node.rightChild) {
    node = node.rightChild;
  }
  return node;
}

Search for a Value

Check if a value exists in the tree:

BinaryTree.prototype.contains = function (target) {
  return searchTree(this.root, target);
};

function searchTree(node, target) {
  if (!node) return false;
  if (target === node.value) {
    return true;
  } else if (target < node.value) {
    return searchTree(node.leftChild, target);
  } else {
    return searchTree(node.rightChild, target);
  }
}

Remove a Node

Removing a node has three cases (no children, one child, two children; replace with in - order successor for two children):

BinaryTree.prototype.remove = function (value) {
  this.root = removeTreeNode(this.root, value);
};

function removeTreeNode(node, value) {
  if (!node) return null;

  if (value < node.value) {
    node.leftChild = removeTreeNode(node.leftChild, value);
    return node;
  } else if (value > node.value) {
    node.rightChild = removeTreeNode(node.rightChild, value);
    return node;
  } else {
    // Case 1: No children
    if (!node.leftChild && !node.rightChild) {
      node = null;
      return node;
    }

    // Case 2: One child
    if (!node.leftChild) {
      node = node.rightChild;
      return node;
    } else if (!node.rightChild) {
      node = node.leftChild;
      return node;
    }

    // Case 3: Two children
    const successor = getMinNode(node.rightChild);
    node.value = successor.value;
    node.rightChild = removeTreeNode(node.rightChild, successor.value);
    return node;
  }
}

Code Testing

const bst = new BinaryTree();
bst.add(11);
bst.add(7);
bst.add(15);
bst.add(5);
bst.add(3);
bst.add(9);
bst.add(8);
bst.add(10);
bst.add(13);
bst.add(12);
bst.add(14);
bst.add(20);
bst.add(25);
bst.add(6);
bst.add(18);

// Pre - order traversal test
let preOrderResult = "";
bst.preOrderTraverse((val) => {
  preOrderResult += val + " ";
});
console.log("Pre - order:", preOrderResult.trim());

// In - order traversal test
let inOrderResult = "";
bst.inOrderTraverse((val) => {
  inOrderResult += val + " ";
});
console.log("In - order:", inOrderResult.trim());

// Min value test
const minVal = bst.findMin();
console.log("Minimum value:", minVal);

// Max value test
const maxVal = bst.findMax();
console.log("Maximum value:", maxVal);

// Search test
const hasEight = bst.contains(8);
console.log("Contains 8:", hasEight);

// Remove test
bst.remove(15);
let updatedInOrder = "";
bst.inOrderTraverse((val) => {
  updatedInOrder += val + " ";
});
console.log("After removing 15 (in - order):", updatedInOrder.trim());

Tags: javascript Data Structures tree Binary Search Tree

Posted on Fri, 21 Aug 2026 16:05:18 +0000 by sks1024