Skip to content

Instantly share code, notes, and snippets.

@pgherveou
Created January 14, 2016 06:00
Show Gist options
  • Save pgherveou/16c7ad88676dcef5adbf to your computer and use it in GitHub Desktop.
Save pgherveou/16c7ad88676dcef5adbf to your computer and use it in GitHub Desktop.
es6 binary search tree
import { inspect } from 'util'
const Tree = Object.create({
init(value) {
this.value = value
this.height = 0
return this
},
getNodeHeight(node) {
if (node) return node.height
return -1
},
[Symbol.iterator]: function*() {
if (this.left) {
for (let v of this.left) { yield v }
}
yield this.value
if (this.right) {
for (let v of this.right) { yield v }
}
},
insert(value) {
// add value to the left
if (this.value > value) {
if (this.left) {
this.left.insert(value)
} else {
this.left = Object.create(Tree).init(value)
}
// add value to the right
} else if (this.value < value) {
if (this.right) {
this.right.insert(value)
} else {
this.right = Object.create(Tree).init(value)
}
}
// recalculate height
this.height = Math.max(
Tree.getNodeHeight(this.left),
Tree.getNodeHeight(this.right)
) + 1
this.balance()
return this
},
isBalanced() {
const leftHeight = Tree.getNodeHeight(this.left)
const rightHeight = Tree.getNodeHeight(this.right)
return Math.abs(leftHeight - rightHeight) <= 1
},
balance() {
const delta = Tree.getNodeHeight(this.left) - Tree.getNodeHeight(this.right)
// right rotation
if (delta > 1) {
const node = Object.create(Tree).init(this.value)
// reset root node
if (this.left.right) {
this.value = this.left.right.value
this.height = this.left.height
// assign right
this.right = node
// adjust the left node
this.left.right = null
this.left.height = 0
} else {
this.value = this.left.value
this.height = this.left.height
// assign right
this.right = node
// adjust the left node
this.left = this.left.left
this.left.height = 0
}
} else if (delta < -1) {
const node = Object.create(Tree).init(this.value)
// reset root node
if (this.right.left) {
this.value = this.right.left.value
this.height = this.right.height
// assign left
this.left = node
// adjust the right node
this.right.left = null
this.right.height = 0
} else {
this.value = this.right.value
this.height = this.right.height
// assign left
this.left = node
// adjust the right node
this.right = this.right.right
this.right.height = 0
}
}
}
})
const tree = Object.create(Tree)
tree.init(26)
.insert(27)
.insert(29)
.insert(30)
.insert(20)
.insert(19)
.insert(18)
.insert(16)
console.log(inspect(tree, { depth: null, colors: true }))
console.log('balance:', tree.isBalanced())
for (let v of tree) { console.log(v) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment