1、 树的术语:
1、节点的度(Degree): 节点的子树的个数
2、树的度:树的所有节点中最大的度数
3、叶节点(Leaf):度为0的节点
4、节点的层次(Level): 规定根节点在1层,其他任一节点的层数是其父节点的层次加1
5、树的深度(Depth): 树中所有节点中的最大层次是这棵树的深度
2、二叉树一些特性:
一个二叉树第i层的最大节点树为:2^(i-1), i >= 1
深度为k的二叉树有最大节点总数为:2^k - 1, k >= 1
对任何非空二叉树T, 若n0表示叶节点的个数,n2是度为2的非叶子节点个数,那么二者满足关系n0 = n2 + 1
3、完美二叉树:
完美二叉树(Perfect Binary Tree),也称满二叉树(Full Binary Tree):
在二叉树中,除了最下层的叶节点外,每层节点都有2个子节点,就构成满二叉树。
4、完全二叉树
完全二叉树(Complete Binary Tree):
除二叉树最后一层外,其他各层的节点树都达到最大个数
且最后一层葱做向右的叶节点连续存在,只缺右侧若干节点。
完美二叉树是特殊的完全二叉树。
下面这个不是完全二叉树,去掉J节点和K节点就是完全二叉树,
或者在D节点下加一个I节点就是完全二叉树
5、二叉搜索树
二叉搜索树(BST, Binary Search Tree),也称二叉排序树或二叉查找树
二叉搜索树是一颗二叉树,可以为空
如果不为空,满足一下性质:
(1)、非空左子树的所有键值小于其根节点的键值
(2)、非空右子树的所有键值大于其根节点的键值
(3)、左、右子树本身也都是二叉搜索树
二叉搜索树常见的操作:
insert(key): 向树中插入一个新的键
search(key):在数中查找一个键,如果节点存在,则返回true; 如果不存在,则返回false
inOrderTraverse:通过中序遍历方式遍历所有节点
preOrderTraverse: 通过先序遍历方式遍历所有节点
postOrderTraverse:通过后序遍历方式遍历所有节点
min: 返回树中最小的值/键
max: 返回树中最大的值/键
remove(key): 从树中移除某个键
二叉搜索树删除操作:
如果删除的节点有两个子节点,甚至子节点还有子节点,这个时候需要从下面的子节点中找到一个节点来替换当前的节点。
要找到来替换current的节点,应该是current节点下面所有节点中最接近current节点的。
比current小一点点,一定是current左子树的最大值
比current大一点点,一定是current右子树的最小值
在二叉搜索树中,这两个特殊的节点叫做前驱和后继
// 创建BinarySearchTree
function BinarySerachTree() {
// 创建节点构造函数
function Node(key) {
this.key = key
this.left = null
this.right = null
}
// 保存根的属性
this.root = null
// 二叉搜索树相关的操作方法
// 向树中插入数据
BinarySerachTree.prototype.insert = function (key) {
// 1.根据key创建对应的node
var newNode = new Node(key)
// 2.判断根节点是否有值
if (this.root === null) {
this.root = newNode
} else {
this.insertNode(this.root, newNode)
}
}
BinarySerachTree.prototype.insertNode = function (node, newNode) {
if (newNode.key < node.key) {
// 1.准备向左子树插入数据
if (node.left === null) {
// 1.1.node的左子树上没有内容
node.left = newNode
} else {
// 1.2.node的左子树上已经有了内容
this.insertNode(node.left, newNode)
}
} else {
// 2.准备向右子树插入数据
if (node.right === null) {
// 2.1.node的右子树上没有内容
node.right = newNode
} else {
// 2.2.node的右子树上有内容
this<