本文参考《数据结构与算法JavaScript描述》一书,根据我的学习心得详述了以下几点内容:
- 树的定义
- 二叉查找树的实现
- 二叉查找树的遍历
- 二叉查找树的查找
- 如何删除二叉查找树上的节点
二叉树的术语
一棵树最上面的节点称为根节点,如果一个节点下面连接多个节点,那么该节点称为父节点,它下面的节点称为子节点。一个节点可以有 0 个、1 个或2个子节点。没有任何子节点的节点称为叶子节点。
如图中所示,沿着一组特定的边,可以从一个节点走到另外一个与它不直接相连的节
点。从一个节点到另一个节点的这一组边称为路径,在图中用虚线表示。以某种特定顺序
访问树中所有的节点称为树的遍历。
树可以分为几个层次,根节点是第 0 层,它的子节点是第 1 层,子节点的子节点是第 2
层,以此类推。我们定义树的层数就是树的深度。
最后,每个节点都有一个与之相关的值,该值有时被称为键。
在使用 JavaScript 构建二叉树之前,需要给我们关于树的词典里再加两个新名词。一个父节点的两个子节点分别称为左节点和右节点。在一些二叉树的实现中,左节点包含一组特定的值,右节点包含另一组特定的值。
前面可能看的有些着急,接下来就是干货啦!开始实现二叉查找树!
二叉查找树由节点组成,所以我们要定义的第一个对象就是 Node。我们通过一个构造函数来实现,它被用来实例化一个一个的节点:
function Node(data,left,right) {
this.data = data; //储存键值
this.left = left; //储存左节点
this.right = right; //储存右节点
this.show = show; //展示节点键值的方法
}
function show() {
return this.data;
}
Node 对象既保存数据,也保存和其他节点的链接(left 和 right),show() 方法用来显示保存在节点中的数据。
现在可以创建一个类,用来表示二叉查找树(BST),可以看到里边已经添加了很多属性方法,后面会一个一个讲解如何实现。
//创建一个构造函数BST,用来实例化二叉查找树(BST)对象
function BST() {
this.root = null; //初始根节点定义为null
this.insert = insert; //插入节点方法
}
insert()方法
BST 先要有一个 insert() 方法,用来向树中加入新节点。这个方法有点复杂,需要着重讲解。
首先要创建一个 Node 对象,将数据传入BST对象保存。
其次检查 BST 是否有根节点,如果没有,那么这是棵新树,该节点就是根节点,这个方法到此也就完成了;否则,进入下一步。
如果待插入节点不是根节点,那么就需要准备遍历 BST,找到插入的适当位置。
进入 BST 以后,下一步就要决定将节点放在哪个地方。找到正确的插入点时,会跳出循环。
重点来了!查找正确插入点的算法如下!
- 设根节点为当前节点。
- 如果待插入节点保存的数据小于当前节点,则设新的当前节点为原节点的左节点;反之,执行第 4 步。
- 如果当前节点的左节点为 null,就将新的节点插入这个位置,退出循环;反之,继续执行下一次循环。
- 设新的当前节点为原节点的右节点。
- 如果当前节点的右节点为 null,就将新的节点插入这个位置,退出循环;反之,继续执行下一次循环。
有了上面的算法,就可以开始实现insert方法了。
function insert(data) {
var n = new Node(data,null,null); //实例化一个Node(节点)对象
if (this.root == null){
this.root = n; //如果根节点为空,则取n为根节点
}else{
var current = this.root; //取二叉树的根节点
var parent;
while(true){
parent = current; //父节点等于二叉树的根节点
if(data < current.data){ //如果插入值小于父节点的值,则将current定为左节点属性
current = current.left;
if(current == null){
parent.left = n; //如果这个父节点左节点为空,则取n为左节点
break; //跳出循环
}
}else{
current = current.right; //如果插入值大于父节点的值,则将current定为右节点属性
if(current == null){
parent.right = n; //如果这个父节点右节点为空,则取n为右节点
break; //跳出循环
}
}
}
}
return this; //实现insert方法的链式调用。
}
new BST().insert(30).insert(24).insert(50).insert(5).insert(18);
将构造函数Node,构造函数BST,insert方法拼在一起执行,就能得到一个二叉树了,非常有意思!
遍历二叉查找树
二叉树的查找分为中序遍历,先序遍历,后序遍历,它们的实现方法请见我的下一篇博客。