📕
Dan Fitz's Notes
  • README
  • Ai
    • Supervised Machine Learning
      • Introduction To Machine Learning
      • Regression With Multiple Input Variables
      • Classification
  • Csharp
    • C Sharp Advanced
      • Generics
      • Delegates
      • Lambda Expressions
      • Events
    • C Sharp Fundamentals
      • Intro To C
      • Primitive Types And Expressions
      • Non Primitive Types
      • Control Flow
      • Arrays And Lists
      • Working With Dates
      • Working With Text
      • Working With Files
      • Debugging Applications
    • C Sharp Intermediate
      • Classes
      • Association Between Classes
      • Inheritance
      • Polymorphism
      • Interfaces
  • Java
    • Inheritance Data Structures Java
      • Inheritance Polymorphism Using Overriding And Access Modifiers
      • Abstract Classes And Debugging
      • File I O And Exceptions
      • Collections Maps And Regular Expressions
    • Intro To Java
      • Introduction To Java Classes And Eclipse
      • Unit Testing Arrays And Array Lists
      • Static Variables Methods And Polymorphism Using Overloading
  • Javascript
    • Algorithms Data Structures
      • Big O Notation
      • Analyzing Performance Of Arrays And Objects
      • Problem Solving Approach
      • Problem Solving Patterns
      • Recursion
      • Searching Algorithms
      • Bubble Selection And Insertion Sort
      • Merge Sort
      • Quick Sort
      • Radix Sort
      • Data Structures Introduction
      • Singly Linked Lists
      • Doubly Linked Lists
      • Stacks And Queues
      • Binary Search Trees
      • Tree Traversal
      • Binary Heaps
    • Complete Nodejs
      • Understanding Node.js
      • REST AP Is And Mongoose
      • API Authentication And Security
      • Node.js Module System
      • File System And Command Line Args
      • Debugging Node.js
      • Asynchronous Node.js
      • Web Servers
      • Accessing API From Browser
      • Application Deployment
      • Mongo DB And Promises
    • Complete React Native
      • Working With Content
      • Building Lists
      • Navigating Users Between Screens
      • State Management
      • Handling Screen Layout
      • Setting Up An App
      • More On Navigation
      • Advanced Statement Management With Context
      • Building A Custom Express API
      • In App Authentication
    • Epic React
      • React Fundamentals
      • React Hooks
      • Advanced React Hooks
      • Advanced React Patterns
      • React Performance
    • Fireship Firestore
      • Firestore Queries And Data Modeling Course
      • Model Relational Data In Firestore No SQL
    • Functional Light Javascript
      • Intro
      • Function Purity
      • Argument Adapters
      • Point Free
      • Closure
      • Composition
      • Immutability
      • Recursion
      • List Operations
      • Transduction
      • Data Structure Operations
      • Async
    • Js Weird Parts
      • Execution Contexts And Lexical Environments
      • Types And Operators
      • Objects And Functions
      • Object Oriented Java Script And Prototypal Inheritance
      • Defining Objects
    • Mastering Chrome Dev Tools
      • Introduction
      • Editing
      • Debugging
      • Networking
      • Auditing
      • Node.js Profiling
      • Performance Monitoring
      • Image Performance
      • Memory
    • React Complete Guide
      • What Is React
      • React Basics
      • Rendering Lists And Conditionals
      • Styling React Components
      • Debugging React Apps
      • Component Deep Dive
      • Building A React App
      • Reaching Out To The Web
      • Routing
    • React Testing
      • Intro To Jest Enzyme And TDD
      • Basic Testing
      • Redux Testing
      • Redux Thunk Testing
    • Serverless Bootcamp
      • Introduction
      • Auction Service Setup
      • Auction Service CRUD Operations
      • Auction Service Processing Auctions
    • Testing Javascript
      • Fundamentals Of Testing
      • Static Analysis Testing
      • Mocking Fundamentals
      • Configuring Jest
      • Test React Components With Jest And React Testing Library
    • Typescript Developers Guide
      • Getting Started With Type Script
      • What Is A Type System
      • Type Annotations In Action
      • Annotations With Functions And Objects
      • Mastering Typed Arrays
      • Tuples In Type Script
      • The All Important Interface
      • Building Functionality With Classes
    • Web Performance With Webpack
      • Intro
      • Code Splitting
      • Module Methods Magic Comments
  • Other
    • Algo Expert
      • Defining Data Structures And Complexity Analysis
      • Memory
      • Big O Notation
      • Logarithm
      • Arrays
      • Linked Lists
      • Hash Tables
      • Stacks And Queues
      • Strings
      • Graphs
      • Trees
    • Aws Solutions Architect
      • AWS Fundamentals IAM EC 2
    • Fundamentals Math
      • Numbers And Negative Numbers
      • Factors And Multiples
      • Fractions
    • Mysql Bootcamp
      • Overview And Installation
      • Creating Databases And Tables
      • Inserting Data
      • CRUD Commands
      • The World Of String Functions
      • Refining Our Selections
      • The Magic Of Aggregate Functions
    • Random Notes
      • Understanding React Hooks
  • Python
    • Data Analysis Using Python
      • Loading Querying And Filtering Data Using The Csv Module
      • Loading Querying Joining And Filtering Data Using Pandas
      • Summarizing And Visualizing Data
    • Intro To Python
      • Course Introduction Intro To Programming And The Python Language Variables Conditionals Jupyter Notebook And IDLE
      • Intro To Lists Loops And Functions
      • More With Lists Strings Tuples Sets And Py Charm
      • Dictionaries And Files
Powered by GitBook
On this page
  • What is A Tree?
  • What is NOT a tree?
  • Uses for trees
  • Comparing trees to lists
  • Binary Search Trees
  • How sorting works
  • How searching works
  • Implementation
  • Classes
  • Insert
  • Find
  • Big O
  1. Javascript
  2. Algorithms Data Structures

Binary Search Trees

What is A Tree?

A tree is a data structure consisting of nodes in a parent-child relationship. The resultant structure is a series of branches that split to varying degrees.

Terminology:

  • Root: The top node

  • Child: A node directly connected to another node when moving away from the root

  • Parent: The reverse notion of a child

  • Siblings: Nodes with the same parent

  • Leaf: A node with no children

  • Edge: The connection between one node and another

What is NOT a tree?

  • Trees must not have its siblings pointing to each other

  • Trees must not have children pointing to parents

  • Trees must not have more than one root parent node

Uses for trees

  • HTML DOM

    • Elements have children, which may have children, and so on

  • Network routing

    • Sending information across a network

  • Abstract syntax trees

    • When code is read, many languages create a tree of syntax commands to make it easier to validate and/or parse the code

  • Artificial intelligence

    • When an AI plays a game, it sometimes utilizes a minimax tree (a kind of decision tree), which is a traversal of every possible move the AI could make, helping it decide which move guarantees a win

  • Folders in operating systems

Comparing trees to lists

Lists are linear: they have a single path. Trees are nonlinear: you can follow multiple different paths.

Think of a singly linked list as a special case of a tree: a tree with only one branch.

Binary Search Trees

Note: There are dozens of kinds of trees, but we'll only focus on binary search trees.

Binary trees are trees where its nodes can have, at most, 2 children.

Binary search trees (BSTs) are special cases of binary trees where they are sorted in a particular way to make it easy to search for nodes.

Because of the need to sort the tree, the data in a binary search tree needs to be sortable via comparison.

How sorting works

The basic idea behind sorting in BSTs is this: every value less than the target node is on the left side of the tree, and every value greater than the target node is on the right side.

How searching works

With your BST sorted, you just ask: is my intended value larger or smaller than the current node? If it's smaller, you can effectively eliminate half of the nodes in your tree and focus your attention on only the left node.

You simply do this over and over as you go down the tree until you find your value (or reach a leaf).

Implementation

Classes

This is enough to get started:

class BinarySearchTree {
  constructor() {
    this.root = null
  }
}

class Node {
  constructor(val) {
    this.val = val
    this.left = null
    this.right = null
  }
}

Insert

Insertion depends on performing comparison in order to find the right place to add a new node.

Here's the pseudocode:

  1. Create a new node.

  2. If there is no root, the node becomes the root.

  3. If there is a root, check if the value is smaller or larger.

  4. If it's smaller, repeat steps 2 and/or 3 except for the left node.

  5. If it's larger, repeat steps 2 and/or 3 except for the right node.

  6. Return the tree when you find a place for the new node.

// Iterative solution
insert(val) {
  const node = new Node(val)

  let ref = this
  let position = 'root'

  while (ref[position] !== null) {
    if (node.val < ref[position].val) {
      ref = ref[position]
      position = 'left'
    } else if (node.val > ref[position].val) {
      ref = ref[position]
      position = 'right'
    } else { // <= equality
      return
    }
  }

  ref[position] = node
  return this
}

// Recursive solution
insert(val, current=this.root) {
  const node = new Node(val)
}

Pro tip: There's 2 common approaches to handling duplicate values:

  • You can ignore it and just return undefined (like in the code above).

  • You can add a count property to your node that increments when duplicates are found.

Find

Finding a node in a BST is basically the same idea as inserting:

  1. Start at the root.

  2. If there is no root, you're done.

  3. If there is a root, compare the value you're searching for with the root node.

  4. If it's equal, return the node.

  5. If it's smaller, repeat steps 2-4 for the left node.

  6. If it's larger, repeat steps 2-4 for the right node.

find(val) {
  let current = this.root

  while (current && val !== current.val) {
    if (val < current.val) {
      current = current.left
    } else {
      current = current.right
    }
  }

  return current ? current : undefined
}

Big O

Typical of binary search, insert and find are both O(log n) in the best and average case. That's because each comparison, on average, eliminates half of the nodes that need to be searched through.

However, in the worst case, you could have a one-sided binary search tree where all values are on the right (or left). In this scenario, insert and find would be O(n).

PreviousStacks And QueuesNextTree Traversal

Last updated 3 years ago