树结构
树是一种分层数据的抽象模型。常见树的例子有家谱,公司的组织架构
树相关的术语
由上图看得出树是一些节点的集合,总结一下树的一些基本概念:
-
节点:树中的数据元素都称之为节点
-
根:最上面的结点称之为根,一颗树只有一个根且由根发展而来,从另外一个角度来说,每个结点都可以认为是其子树的根
-
父亲:结点的上层结点,如图中,结点K的父亲是E、结点L的父亲是G
-
兄弟:具有相同父亲的结点称为兄弟,图中F、G、H互为兄弟
-
结点的度:结点所拥有的子树的个数称之为结点的度,如结点B的度为3
-
树叶:度为0的结点,也叫作终端结点,图中D、K、F、L、H、I、J都是树叶
-
分支结点:度不为0的结点,也叫作非终端结点或内部结点,图中根、A、B、C、E、G都是分支结点
-
结点的层次:从根节点到树中某结点所经路径上的分支树称为该结点的层次,根节点的层次规定为1,其余结点的层次等于其父亲结点的层次+1
-
树的深度:树中结点的最大层次数,图中树的深度为4
二叉树和二叉搜索树(BST)
二叉树中的节点最多只能有两个子节点:一个左侧子节点,一个右侧子节点。
二叉搜索树规定只允许在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大的值。
创建BinarySearchTree类
代码块
class Node{
constructor(element){
this.element = element;
this.left = null;
this.right = null;
}
}
class Tree{
constructor(){
this.root = null;
}
//插入节点
insert(element){
let node = new Node(element);
if(this.root == null){//第一次添加
this.root = node;
}else{
this.insertNode(node,this.root)
}
}
//迭代插入节点
insertNode(newNode,rootNode){
if(newNode.element < rootNode.element){//左侧节点
if(rootNode.left == null){
rootNode.left = newNode
}else{
this.insertNode(newNode,rootNode.left)
}
}else{//右侧节点
if(rootNode.right == null){
rootNode.right = newNode
}else{
this.insertNode(newNode,rootNode.right)
}
}
}
//查找最大值
min(){
return this.minNode(this.root)
}
//查找最大值迭代
minNode(node){
while (node.left != null) {
node = node.left
}
return node
}
//查找最小值
max(){
return this.maxNode(this.root)
}
//查找最小值迭代
maxNode(node){
while (node.right != null) {
node = node.right
}
return node
}
//查找节点是否存在
search(element){
return this.searchNode(element,this.root)
}
searchNode(newNode,rootNode){
if(rootNode == null){
return false;
}
if(newNode < rootNode.element){//右侧
return this.searchNode(newNode,rootNode.left);
}else if(newNode > rootNode.element){//左侧
return this.searchNode(newNode,rootNode.right);
}else{//==
return true;
}
}
//中序遍历
inoderTarvares(callback){
this.inoderTarvaresNode(this.root,callback)
}
//中序遍历查找迭代
inoderTarvaresNode(rootNode,callback){
if(rootNode !== null){
this.inoderTarvaresNode(rootNode.left,callback);
callback(rootNode.element);
this.inoderTarvaresNode(rootNode.right,callback)
}
}
//前序遍历
prevoderTarvares(callback){
this.prevoderTarvaresNode(this.root,callback);
}
//前序遍历查找迭代
prevoderTarvaresNode(rootNode,callback){
if(rootNode !== null){
callback(rootNode.element);
this.prevoderTarvaresNode(rootNode.left,callback);
this.prevoderTarvaresNode(rootNode.right,callback);
}
}
//后序遍历
postoderTarvares(callback){
this.postoderTarvaresNode(this.root,callback);
}
//后序遍历查找迭代
postoderTarvaresNode(rootNode,callback){
if(rootNode !== null){
this.postoderTarvaresNode(rootNode.left,callback);
this.postoderTarvaresNode(rootNode.right,callback);
callback(rootNode.element);
}
}
}
let t = new Tree();
t.insert(11);
t.insert(10);
t.insert(20);
t.insert(9);
t.insert(5);
console.log(t.search(1))
let callback = (element)=>{
console.log(element)
}
t.inoderTarvares(callback)
t.prevoderTarvares(callback)
console.log(t.min())