[Algorithms] Build a Binary Tree in JavaScript and Several Traversal Algorithms

A binary tree is a tree where each node may only have up to two children. These children are stored on the leftand right properties of each node.

When traversing a binary tree, we have three common traversal algorithms: in order, pre-order, and post-order. In this lesson, we write each of these algorithms and explore their differences.

 

// Binary Trees and Tree Traversal

// Binary trees are trees whose nodes can only have up to two children

function createBinaryNode(key) {
    return {
      key,
      left: null,
      right: null,
      addLeft(leftKey) {
        const newLeft = createBinaryNode(leftKey)
        this.left = newLeft
        return newLeft
      },
      addRight(rightKey) {
        const newRight = createBinaryNode(rightKey)
        this.right = newRight
        return newRight
      }
    }
  }
  
  const TRAVERSALS = {
    /**
     * Javascript Call stack is Last in, First Out,
     * So it keep calling 
     *      TRAVERSALS.IN_ORDER(node.left, visitFn)
     * Until it reach the bottom left node 'h' (b- d- h)
     *      h - visitFn get called
     *      h - TRAVERSALS.IN_ORDER(node.right, visitFn) get called
     *      
     *      d - visitFn get called
     *      d - left
     *      d - right 
     * 
     *      b - visitFn
     *      b - left
     *      b - right
     */
    IN_ORDER: (node, visitFn) => {
      if (node !== null) {
        console.log('left', node.left && node.left.key)
        TRAVERSALS.IN_ORDER(node.left, visitFn)
        console.log('call', node.key)
        visitFn(node)
        console.log('right', node.right && node.right.key)
        TRAVERSALS.IN_ORDER(node.right, visitFn)
      }
    },
    PRE_ORDER: (node, visitFn) => {
      if (node !== null) {
        visitFn(node)
        TRAVERSALS.PRE_ORDER(node.left, visitFn)
        TRAVERSALS.PRE_ORDER(node.right, visitFn)
      }
    },
    POST_ORDER: (node, visitFn) => {
      if (node !== null) {
        TRAVERSALS.POST_ORDER(node.left, visitFn)
        TRAVERSALS.POST_ORDER(node.right, visitFn)
        visitFn(node)
      }
    }
  }
  
  function createBinaryTree(rootKey) {
    const root = createBinaryNode(rootKey)
  
    return {
      root,
      print(traversalType = 'IN_ORDER') {
        let result = ''
  
        const visit = node => {
          result += result.length === 0 ? node.key : ` => ${node.key}`
        }
  
        TRAVERSALS[traversalType](this.root, visit)
  
        return result
      }
    }
  }
  
  const tree = createBinaryTree('a')
  const b = tree.root.addLeft('b')
  const c = tree.root.addRight('c')
  const d = b.addLeft('d')
  const e = b.addRight('e')
  const f = c.addLeft('f')
  const g = c.addRight('g')
  const h = d.addLeft('h')
  const i = d.addRight('i')
  
  console.log('IN_ORDER: ', tree.print())// IN_ORDER: h => d => i => b => e => a => f => c => g
//console.log('PRE_ORDER: ', tree.print('PRE_ORDER')) // PRE_ORDER: a => b => d => h => i => e => c => f => g
  
  //console.log('POST_ORDER: ', tree.print('POST_ORDER')) // POST_ORDER: h => i => d => e => b => f => g => c => a
  
  exports.createBinaryNode = createBinaryNode
  exports.createBinaryTree = createBinaryTree
  

 

Time complexity: O(n),

Space Complexity O(h) for average cases; h = logN -- this is because we need to stack all the function calls. worse cases: O(n)

 

posted @ 2018-12-20 04:22  Zhentiw  阅读(274)  评论(0编辑  收藏  举报