BTS 二叉搜索树
1、什么是二叉搜索树?
在计算机科学中,树与现实的树结构是一样的,但是它是倒着的。
二叉搜索树(BST)是树的一种,它有一个根节点,每个节点大于父节点的置于父节点的右侧,小于父节点的值的,存储在父节点的左侧。
2、创建一个二叉搜索树?
-
需要一个 节点类 来表示BTS中的每个节点。
-
需要一个 比较函数 来判断新的节点应处于什么位置
-
需要一个 BTS类 来种一个树,且正确的处置每个节点
-
创建节点类
class Node{ constructor(key){ this.key = key this.left = null this.irght = null } } -
写一个比较函数
const function compareFn (a,b){ if(a===b) return COMPARE.EQUALS a < b ? COMPARE.LESS : COMPARE.BIG } const COMPARE = { BIG : 1, LESS : -1, EQUALS : 0 } -
创建BTS类
class BSTree{ constructor(compare = compareFn){ this.compare = compare this.root = null } .... }
3、创建BST树最重要的方法 insert(key) 将一个值 插入到树中
-
insert(key) 接着上面的 BSTree 类写
{ insert(key){ if(this.root == null){ //1.思路:判断这个树的root节点是否为null this.root = new Node(key) }else{ //2.若不为null,则要为其安排一个正确的位置插入 this.insertNode(this.root,key) } } insertNode(node,key){ //3.思路:若key比node小,key在左侧插入 if(this.compare(node,key) === COMPARE.BIG){ //3.1判断左侧是否有节点 if(node.left == null){ node.left = new Node(key) }else{ this.insert(node.left,key) //3.2若左侧有节点,则递归操作,重新找到合适的位置。 } }else{ //4.反之在右侧插入 if(node.right == null){ node.right = new Node(key) //4.1 }else{ this.insertNode(node.right,key) //4.2 } } } ...... }
在一棵树中,插入一个节点需要考虑2种情况
- 树的 根节点为 null , 将该 node 设为这棵树的根,
- 树的 根节点不为 null ,又可以细分2种情况
- 1)node 值小于 root 的值,在左侧插入;又可细分 2种情况
- 左侧没有值,将 node 设为左侧节点
- 左侧 有值,递归调用,继续找到树的下一层。 => 重复 第 2 情况
- 2)node 值大于 root的值,在右侧插入;又可细分 2种情况
- 右侧没有值,将 node 设为右侧节点
- 右侧 有值,递归调用,继续找到树的下一层。=> 重复 第 2 情况
这个过程,也像是一棵树。
4、创建 先序遍历、中序遍历、后序遍历
-
通常把调用和遍历分开,于是我们这样写
{ //先序遍历 preOder(callback){ this.preOderNode(this.root,callback) } //中序遍历 inOder(callback){ this.inOderNode(this.root,callback) } //先后序遍历 postOder(callback){ this.postOderNode(this.root,callback) } ...... } -
三种方法的区别在哪里?
- 区别只在遍历根节点的顺序不同。
-
创建 先序搜索
{ preOderNode(node,callback){ if(this.node != null){ callback(node.key) //先序就是先遍历 this.preOderNode(node.left,callback) this.preOderNode(node.right,callback) } } ...... }
-
创建 中序遍历
{ inOderNode(node,callback){ if(this.node != null){ this.inOderNode(node.left,callback) callback(node.key) //中序就是在中遍历 this.inOderNode(node.right,callback) } } ...... }
3. 创建 后序遍历
{
postOderNode(node,callback){
if(this.node != null){
this.postOderNode(node.left,callback)
this.postOderNode(node.right,callback)
callback(node.key) //后序就是后遍历
}
}
......
}
5、校验是否正确
const tree = new BSTTree()
tree.insert(11)
tree.insert(7)
tree.insert(15)
tree.insert(5)
tree.insert(3)
tree.insert(9)
tree.insert(8)
tree.insert(10)
tree.insert(13)
tree.insert(12)
tree.insert(14)
tree.insert(20)
tree.insert(18)
tree.insert(25)
tree.insert(6)
console.log(tree)
let index = []
tree.inOrder((node) => {
index.push(node.key)
// console.log(node)
})
let pre = []
tree.preOrder((node) => {
pre.push(node.key)
// console.log(node)
})
let post = []
tree.postOrder((node) => {
post.push(node.key)
// console.log(node)
})
console.log(index)
console.log(pre)
console.log(post)
/** Console **/
BSTTree {root: Node, compare: ƒ}
BSTTree.js:144 (15) [3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18, 20, 25]
BSTTree.js:145 (15) [11, 7, 5, 3, 6, 9, 8, 10, 15, 13, 12, 14, 20, 18, 25]
BSTTree.js:146 (15) [3, 6, 5, 8, 10, 9, 7, 12, 14, 13, 18, 25, 20, 15, 11]
学习数据结构和算法,应该在熟悉和了解,再谈掌握!希望大家学习进步!