JS 實現 二叉樹

① 二叉樹定義
② 二叉排序樹
③ 二叉平衡樹node

① 二叉樹定義

二叉樹(Binary tree)是每一個節點最多隻有兩個分支(不存在分支度大於2的節點)的樹結構。一般分支被稱爲「左子樹」和「右子樹」。二叉樹的分支具備左右次序,不能顛倒。chrome

② 二叉排序樹

簡單定義
二叉排序樹 又稱爲 二叉搜索樹或二叉查找樹
特徵
(1) 若它的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值
(2) 若它的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值
(3) 它的左、右子樹也分別爲二叉查找樹
Javascript實現函數

function BinarySearchTree(keys){
  //Node構造函數
  let Node = function (key){
     this.key = key
     this.left = null
     this.right = null
  }
  let root = null
  let insertNode = (node,newNode)=>{
     if(newNode.key < node.key){
       if(node.left === null){
         node.left = newNode
       }else {
         insertNode(node.left,newNode)
       }
     }else {
       if (node.right === null) {
         node.right = newNode
       }else {
         insertNode(node.right,newNode)
       }
     }
  }
  this.insert = (key)=>{
     let newNode = new Node(key)
     if (root === null) {
       root = newNode
     }else {
       insertNode(root,newNode)
     }
  }
  keys.forEach((key)=>{
   this.insert(key)
  })
  return root
}
const keys = [8,3,10,1,6,14,4,7,13]
BinarySearchTree(keys)

chrome中打印以下:
圖片描述post

效果圖:
圖片描述this

中序遍歷
中序遍歷的遞歸定義:先左子樹,後根節點,再右子樹spa

let inOrderTraverseFunction =(node,cb)=>{
   if(node!==null){
      inOrderTraverseFunction(node.left,cb)
      cb(node.key)
      inOrderTraverseFunction(node.right,cb)
   }
} 
let callback =(key)=>{
  console.log(key)
}
//BST的中序遍歷
inOrderTraverseFunction(BinarySearchTree(keys),callback)

chrome中打印以下:
圖片描述code

結果:整顆二叉樹節點以從小到大依次顯示blog

前序遍歷
前序遍歷的遞歸定義:先根節點,後左子樹,再右子樹排序

let preOrderTraverseFunction =(node,cb)=>{
   if(node!==null){
      cb(node.key)
      preOrderTraverseFunction(node.left,cb)
      preOrderTraverseFunction(node.right,cb)
   }
} 
//BST前序遍歷
preOrderTraverseFunction(BinarySearchTree(keys),callback)

chrome打印以下
圖片描述遞歸

後序遍歷
後序遍歷的遞歸定義:先左子樹,後右子樹,再根節點

let postOrderTraverseFunction =(node,cb)=>{
   if(node!==null){
      postOrderTraverseFunction(node.left,cb)
      postOrderTraverseFunction(node.right,cb)
      cb(node.key)
   }
} 
//BST後序遍歷
postOrderTraverseFunction(BinarySearchTree(keys),callback)

chrome打印以下
圖片描述

查找BST最小值
白話:即二叉樹左子樹最左側的那個沒有左子樹的節點

let minNode =(node)=>{
  if(node){
    while (node&&node.left !== null){
       node = node.left
    }
    return node.key
  }
  return null
}
//查找BST最小值
console.log('the min node is '+minNode(BinarySearchTree(keys)))

chrome打印以下
圖片描述

查找BST最大值
白話:即二叉樹右子樹最右側的那個沒有右子樹的節點

let maxNode =(node)=>{
  if(node){
    while (node&&node.right !== null){
       node = node.right
    }
    return node.key
  }
  return null
}
//查找BST最大值
console.log('the max node is '+maxNode(BinarySearchTree(keys)))

chrome打印以下
圖片描述

查找BST某個值
即將該值和每一個節點比較 若是該值比此節點小 則進入左子樹再遞歸比較 反之 若是該值比此節點大 則進入右子樹再遞歸比較

let searchNode = (node,key)=>{
  if(node === null){
    return false   
  }
  if(key<node.key){
    return searchNode(node.left,key)
  }else if (key>node.key) {
    return searchNode(node.right,key)
  }else{
    return true
  }
}
//BST查找某個值
console.log(searchNode(BinarySearchTree(keys),3)?'node 3 is found':'node 3 is not found')
console.log(searchNode(BinarySearchTree(keys),5)?'node 5 is found':'node 5 is not found')

chrome打印以下:
圖片描述

刪除BST某個葉子節點
葉子節點:沒有左子樹和右子樹的節點

let removeNode = (node,key)=>{
  if(node === null){
    return null
  }
  if(key<node.key){
    node.left = removeNode(node.left,key)
    return node
  }else if(key>node.key){
    node.right = removeNode(node.right,key)
    return node
  } else{
    if(node.left === null && node.right === null){
      node = null
      return node
    }
  }
}
//BST刪除某個葉子節點
console.log(removeNode(BinarySearchTree(keys),1),BinarySearchTree(keys))

chrome打印以下:
圖片描述

效果圖:
圖片描述

刪除BST某個度爲1的節點

let removeNode = (node,key)=>{
  if(node === null){
    return null
  }
  if(key<node.key){
    node.left = removeNode(node.left,key)
    return node
  }else if(key>node.key){
    node.right = removeNode(node.right,key)
    return node
  } else{
    if(node.left === null && node.right === null){
      node = null
      return node
    }
    if(node.left === null){
      node = node.right
      return node
    }else if (node.right === null) {
      node = node.left
      return node     
    }
  }
}
//BST刪除某個度爲1的子節點
console.log(removeNode(BinarySearchTree(keys),10),BinarySearchTree(keys))

chrome打印以下:
圖片描述

效果圖:
圖片描述

刪除BST某個度爲2的節點

let findMinNode = (node) =>{
  if(node){
    while(node&& node.left !== null){
      node = node.left
    }
    return node 
  }
  return null
}
let removeNode = (node,key)=>{
  if(node === null){
    return null
  }
  if(key<node.key){
    node.left = removeNode(node.left,key)
    return node
  }else if(key>node.key){
    node.right = removeNode(node.right,key)
    return node
  } else{
    if(node.left === null && node.right === null){
      node = null
      return node
    }
    if(node.left === null){
      node = node.right
      return node
    }else if (node.right === null) {
      node = node.left
      return node     
    }
    let minNode = findMinNode(node.right) 
    node.key = minNode.key
    node.right = removeNode(node.right,minNode.key)
    return node
  }
}
//BST刪除某個度爲2的子節點
console.log(removeNode(BinarySearchTree(keys),3),BinarySearchTree(keys))

chrome打印以下:
圖片描述

效果圖:
圖片描述

未完待續

相關文章
相關標籤/搜索