相关术语
根节点:树顶部的节点
内部节点:至少有一个子节点的节点
外部节点或叶节点:没有子元素的节点
子树:由节点和它的后代构成
深度:节点的深度取决于它的祖先节点的数量
高度:取决于所有节点深度的最大值

二叉树和二叉搜索树
二叉树
- 节点最多只能有两个子节点,一个是左侧子节点,另一个是右侧子节点。
二叉搜索树
- 是二叉树的一种
- 只允许在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大的值。
代码实现
创建二叉树的每个节点
export class Node{
constructor(key){
this.key = key
this.left = null
this.right = null
}
}
创建树类及其各类方法
export default class Tree {
constructor(){
this.root = null
}
insert(value){}
search(value){}
inOrderTraverse(callback){}
preOrderTraverse(callback){}
min(){}
max(){}
remove(value){}
insertNode(node,newNode){
if(newNode.key > node.key){
if(node.right === null){
node.right = newNode
}else{
this.insertNode(node.right,newNode)
}
}else if(newNode.key < node.key){
if(node.left === null){
node.left = newNode
}else{
this.insertNode(node.left,newNode)
}
}
}
getRoot(){
return this.root
}
}
添加元素
insert(value){
let newNode = new Node(value)
if(this.root === null){
this.root = newNode
}else{
this.insertNode(this.root,newNode)
}
}
通过中序遍历方式遍历所有节点。
inOrderTraverse(callback){
this.inOrderTraverseNode(this.root,callback)
}
inOrderTraverseNode(node,callback){
if(node !== null){
this.inOrderTraverseNode(node.left,callback)
callback(node.key)
this.inOrderTraverseNode(node.right,callback)
}
}
通过先序遍历方式遍历所有节点。
preOrderTraverse(callback){
this.preOrderTraverseNode(this.root,callback)
}
preOrderTraverseNode(node,callback){
if(node !== null){
callback(node.key)
this.preOrderTraverseNode(node.left,callback)
this.preOrderTraverseNode(node.right,callback)
}
}
通过后序遍历方式遍历所有节点。
postOrderTraverse(callback){
this.postOrderTraverseNode(this.root,callback)
}
postOrderTraverse(callback){}
postOrderTraverseNode(node,callback){
if(node !== null){
this.postOrderTraverseNode(node.left,callback)
this.postOrderTraverseNode(node.right,callback)
callback(node.key)
}
}
返回树中最小的值/键。
min(){
return this.minNode(this.root)
}
minNode(node){
let current = node
while(current !== null && current.left !== null){
current = current.left
}
return current
}
返回树中最大的值/键。
max(){
return this.maxNode(this.root)
}
maxNode(node){
let current = node
while(current !== null && current.right !== null){
current = current.right
}
return current
}
查找节点
search(value){
return this.searchNode(this.root,value)
}
searchNode(node,value){
if(node === null) return false
if(value > node.key){
this.searchNode(node.right,value)
}else if(value < node.key){
this.searchNode(node.left,value)
}else{
return true
}
}
移除节点
- 删除的原理是重新构建树
- 有两个子节点时将移除的节点替换为右侧子树的最小节点
remove(value){
this.root = this.removeNode(this.root,value)
}
removeNode(node,value){
if(root !== null){
if(value > node.key){
this.removeNode(node.right,value)
}else if(value < node.key){
this.removeNode(node.left,value)
}else{
if(node.left === null && node.right === null){
node = null
return node
}
if(node.left === null && node.right !== null){
return node.right
}else if(node.left !== null && node.right === null){
return node.left
}else if(node.left !== null && node.right !== null){
let minNode = this.findMinNode(node.right)
node.key = minNode.key/将查找到的节点的值赋给当前节点
node.right = this.removeNode(node.right,minNode.key)
}
}
}
}
findMinNode(node){
let current = node
while(current && current.left){
current = current.left
}
return cuurent
}