Building a badass BST tree in TypeScript for ⚛️

Published: April 25, 2023

Time to read: 8 min

Building a badass BST tree in TypeScript for ⚛️

Published: April 25, 2023

Time to read: 8 min

Okay folks, buckle up. We're about to embark on a wild ride through the world of computer science, TypeScript, and React. You know, the kind of stuff that makes you the life of the party. Today, we're gonna learn how to build a generic Binary Search Tree (BST) in TypeScript and use it in a React application. And trust me, it's gonna be as edgy as it gets.

What the Hell is a Binary Search Tree?

Before we dive in headfirst, let's make sure we're all on the same page. A Binary Search Tree is a data structure that's been around since your grandpa's first computer. It's a simple, to the point, and ruthlessly efficient. In a BST, each node has at most two children, and all the nodes on the left side are less than the node's value, while those on the right side are greater. It's kinda like organizing your closet, but with a lot less cursing and sweat.

TypeScript, the Unsung Hero

Now, let's talk TypeScript. If JavaScript is the loud, obnoxious guy at the party, TypeScript is his more refined, put-together cousin. TypeScript is a statically typed superset of JavaScript that compiles to plain JavaScript. It's like JavaScript with a hint of class, giving you the benefits of static typing while still letting you live in the wild and crazy world of JS.

Building a Kickass BST in TypeScript

Now that we're all primed and ready, it's time to build our generic BST in TypeScript. We'll start by defining a **Node** class with a constructor to initialize the node's value and left and right children. Then, we'll create a **BinarySearchTree** class that handles all the dirty work, like inserting and searching for nodes, traversing the tree, and doing all those other things you'd expect from a well-behaved BST. All that in a type-safe, TypeScript-y package.

code block is typescript
class TreeNode<T> {
  value: T;
  left: TreeNode<T> | null;
  right: TreeNode<T> | null;

  constructor(value: T) {
    this.value = value;
    this.left = null;
    this.right = null;
  }
}

class BinarySearchTree<T> {
  root: TreeNode<T> | null;

  constructor() {
    this.root = null;
  }

  insert(value: T) {
    const newNode = new TreeNode(value);

    if (!this.root) {
      this.root = newNode;
      return;
    }

    let currentNode = this.root;
    while (true) {
      if (value < currentNode.value) {
        if (!currentNode.left) {
          currentNode.left = newNode;
          return;
        }
        currentNode = currentNode.left;
      } else {
        if (!currentNode.right) {
          currentNode.right = newNode;
          return;
        }
        currentNode = currentNode.right;
      }
    }
  }

  search(value: T): TreeNode<T> | null {
    let currentNode = this.root;
    while (currentNode) {
      if (value === currentNode.value) return currentNode;
      currentNode = value < currentNode.value ? currentNode.left : currentNode.right;
    }
    return null;
  }

  inOrderTraversal(node: TreeNode<T> | null, callback: (value: T) => void): void {
      if (!node) return;
      this.inOrderTraversal(node.left, callback);
      callback(node.value);
      this.inOrderTraversal(node.right, callback);
    }
  
    preOrderTraversal(node: TreeNode<T> | null, callback: (value: T) => void): void {
      if (!node) return;
      callback(node.value);
      this.preOrderTraversal(node.left, callback);
      this.preOrderTraversal(node.right, callback);
    }
  
    postOrderTraversal(node: TreeNode<T> | null, callback: (value: T) => void): void {
      if (!node) return;
      this.postOrderTraversal(node.left, callback);
      this.postOrderTraversal(node.right, callback);
      callback(node.value);
    }
}

React, the UI Whisperer

Alright, now that we've got our snazzy BST all ready to go, let's see how we can use it in a React application. React is that cool, hip framework that's all the rage these days, and it's all about building reusable UI components. If you're not using React, you're like that guy still rocking a flip phone in 2023. So, we'll create a new React component that can visualize our BST, letting us add and remove nodes like a boss.

code block is tsx
import React, { useState } from 'react';
import { BinarySearchTree } from './BinarySearchTree';

const App = () => {
  const [bst, setBst] = useState(new BinarySearchTree<number>());
  const [inputValue, setInputValue] = useState('');

  const handleInsert = (e: React.FormEvent) => {
    e.preventDefault();
    const value = parseInt(inputValue);
    if (!isNaN(value)) {
      bst.insert(value);
      setBst(bst);
      setInputValue('');
    }
  };

  const renderNode = (node: TreeNode<number> | null, depth: number): JSX.Element | null => {
    if (!node) return null;

    return (
      <div style={{ marginLeft: depth * 30 }}>
        <div>{node.value}</div>
        <div style={{ display: 'flex' }}>
          {renderNode(node.left, depth + 1)}
          {renderNode(node.right, depth + 1)}
        </div>
      </div>
    );
  };

  return (
    <div>
      <form onSubmit={handleInsert}>
        <input
          type="text"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
        />
        <button type="submit">Insert</button>
      </form>
      <div>{renderNode(bst.root, 0)}</div>
    </div>
  );
};

export default App;

Conclusion: Mission Accomplished

There you have it, folks. We built ourselves a badass, generic BST in TypeScript and used it in a slick React application. Now, you can go forth and impress all your friends with your newfound knowledge. Or, you know, just build some killer applications that make use of these powerful tools. Either way, you've got some serious BST and TypeScript chops now, and that's definitely something to be proud of.

Now we've got ourselves a fully functional, visually appealing BST in a React application. Users can insert values, and the tree will dynamically render as values are added. Of course, this is just the tip of the iceberg; there are endless possibilities for customizing and expanding upon this basic example.

From here, you could implement additional BST features, such as deletion or balancing, and add more interactivity to the React component, like searching for specific values or animating the tree's growth.

But for now, you've got a solid foundation to build on, and you're well on your way to mastering the art of TypeScript BSTs and their integration with React. So go forth, brave coder, and conquer the world of data structures and web applications with your newfound skills!