二叉樹的順序插入

模擬過程

二叉樹

  1. 插入根節點A
  2. 在父節點A的左下方插入子節點B
  3. 在父節點A的右下方插入子節點C
  4. 在父節點B的左下方插入子節點D
  5. 在父節點B的右下方插入子節點E
  6. 在父節點C的左下方插入子節點F
    ...

分析過程

每次插入節點需明確被插入的父節點以及被插入的位置(左右)node

明確被插入的父節點

第1步中,需將A存儲,由於A在第2,3步中被取出,做爲插入操做的父節點
第2步中,需將B存儲,由於B在第4,5步中被取出,做爲插入操做的父節點
第3步中,需將C存儲,由於C在第6步中被取出,做爲插入操做的父節點,與此同時,A在被執行右下方的插入操做後,A不能再被插入子節點
...
第5步中,需將E存儲,其在後續的操做中會被取出,做爲插入操做的父節點,與此同時,B與A同樣,在被執行右下方的插入操做後,B不能再被插入子節點
建個隊列,將後續操做中會被取出的節點存儲,不會再被取出的節點移除。每次插入的新節點都會入列。同時,若新節點被插入到父節點的右下方,則該父節點出列。this

明確被插入的位置

被插入的位置能夠經過插入的次數來判斷,如果第1次插入,則是根節點,如果第n(n>1)次插入,n爲偶,則插入左邊,n爲奇,則插入右邊
故用個變量存儲插入的次數spa

代碼

運行環境node v8.4prototype

function Node(value) {
  this.value = value
  this.left = null
  this.right = null
}

function BinaryTree() {
  this.root = null // 樹根
  this.queue = [] // 存儲會被使用的父節點
  this.insertNum = 0 // 記錄插入操做的次數
}

BinaryTree.prototype.insert = function (value) {
  this.insertNum++ // 插入次數加1
    let node = new Node(value)
  if (!this.root) { // 判斷根節點是否存在
    this.root = node // 插入根節點
    this.queue.push(this.root) // 新節點入列
  } else { // 插入非根節點
    let parent = this.queue[0] // 被插入的父節點
    if (!(this.insertNum % 2)) { // 經過插入次數判斷左右
      parent.left = node // 插入左邊
      this.queue.push(parent.left) // 新節點入列
    } else {
      parent.right = node // 插入右邊
      this.queue.push(parent.right) // 新節點入列
      this.queue.shift() // 當前父節點parent 已經不可能再插入子節點,故出列
    }
  }
  return this
}

let binaryTree = new BinaryTree()
binaryTree.insert('A')
  .insert('B')
  .insert('C')
  .insert('D')
  .insert('E')
  .insert('F')

console.log(JSON.stringify(binaryTree.root, null, 4))

output.png

插入空節點

插入空節點.png

首先須要判斷插入的節點是否爲空節點
如果空節點,其不會做爲父節點被執行插入操做,故不用入列3d

改進代碼

BinaryTree.prototype.insert = function (value) {
  this.insertNum++ // 插入次數加1
    let node = (!value && typeof value === 'object') ? null : new Node(value) // 判斷是否爲空節點

  if (!this.root) { // 判斷根節點是否存在
    this.root = node // 插入根節點
    node && this.queue.push(this.root) // 非空節點入列
  } else { // 插入非根節點
    let parent = this.queue[0] // 被插入的父節點
    if (!(this.insertNum % 2)) { // 經過插入次數判斷左右
      parent.left = node // 插入左邊
      node && this.queue.push(parent.left) // 非空節點入列
    } else {
      parent.right = node // 插入右邊
      node && this.queue.push(parent.right) // 非空節點入列
      this.queue.shift() // 當前父節點parent 已經不可能再插入子節點,故出列
    }
  }
  return this
}

let binaryTree = new BinaryTree()
binaryTree.insert('A')
  .insert('B')
  .insert('C')
  .insert('D')
  .insert('E')
  .insert(null)
  .insert('F')
  .insert('G')

console.log(JSON.stringify(binaryTree.root, null, 4))

output2.png

相關文章
相關標籤/搜索