树的概念
树是模拟的具有树状结构的一个数据集合,它由n(n>=1)个有限节点组成一个具有层次关系的集合- 每个节点有零个或多个子节点
- 没有父节点的节点称作根节点
- 每一个非根节点有且只有一个父节点
- 除了跟节点外,每个子节点可以分为多个不相交的子树
比如
树的术语
- 节点的度:一个节点含有的子树的个数
- 树的度:一个书中,最大的节点的度成为树的度
- 叶子节点或终端节点:度为0的节点
- 父亲节点或父节点:若一个节点含有子节点,则这个节点成为其子节点的父节点
- 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点
- 兄弟节点:具有相同父节点的节点互称为兄弟节点
- 节点的层次:从根开始定义器,根的子节点为第二层,以此类推
- 书的高度或深度:树中节点的最大层次
- 堂兄弟节点:父节点再同一层节点护卫堂兄弟节点
- 子孙:以某节点韦根的子树中任一个接待你都称之为子孙
二叉排序树
- 每个节点最多含有两个子树的树成为二叉树
- 若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值
- 右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值
节点定义
class treeNode{
constructor(value){
this.value=value //当前节点的值
this.leftC=null //左子节点
this.rightC=null //右子节点
}
}
插入节点的方法
function insert(root,value){
if(!root){
return new treeNode(value) //为空创建节点
}
if(value<root.value){
root.leftC=insert(root.leftC,value) //递归生成左子节点
}else{
root.rightC=insert(root.rightC,value) //递归生成右子节点
}
return root
}
root =new treeNode(3)
root=insert(root,2
节点查找
//通过值查找对应节点
function find(root,value){
if(!root){
return null
}
if(value==root.value){
return root
}
if(value<root.value){
return find(root.leftC,value) //递归查找左子树
}else{
return find(root.rightC,value) //递归查找右子树
}
}
删除节点的方法
删除节点时如果他没有子节点,直接删除没问题,如果删除的节点只有右子节点,或者左子节点,那直接让该子节点替换删除的节点位置就可以了,但是如果有两个子节点为了不破坏二叉树结构,那么可用左子树中最大的或者右子树中最小的替换function del(root,value){
if(!root){
return null
}
if(root.value==value){
if(!root.leftC&&!root.rightC){
return null //没有叶子节点
}else if(root.leftC&&!root.rightC){
return root.leftC //只有左子树
}else if(!root.leftC&&root.rightC){
return root.rightC //只有右子树
}else if(root.leftC&&root.rightC){
x=maxLeft(root.leftC) //左右子树都有
x.rightC=root.rightC
return x
}
}
if(root.value>value){
root.leftC=del(root.leftC,value)
return root
}else{
root.rightC=del(root.rightC,value)
return root
}
function maxLeft(root){ //求左子树中最大值
if(!root.rightC){
return root
}
return maxLeft(root.rightC)
}
}
遍历二叉树
//先序遍历 先根在左再右
function preOrder(root){
if (!root){
return null
}
console.log(root.value)
preOrder(root.leftC)
preOrder(root.rightC)
}
//中序遍历 左根右
function inOrder(root){
if (!root ){
return null
}
inOrder(root.leftC)
console.log(root.value)
inOrder(root.rightC)
}
//后序遍历 右根左
function postOrder(root){
if (!root){
return null
}
postOrder(root.leftC)
postOrder(root.rightC)
console.log(root.value)
}