树
树(Tree)是一种层次化的数据结构,它由节点(Node)和边(Edge)组成。每个节点都有一个值,并且可能有零个或多个子节点。树的一个节点称为根(Root),没有父节点;节点之间的关系分为父节点、子节点和兄弟节点。
一、基本概念:
- 根节点(Root): 树的顶端节点,没有父节点。
- 子节点(Child): 树中的节点,有一个父节点。
- 父节点(Parent): 有子节点的节点。
- 叶子节点(Leaf): 没有子节点的节点,位于树的末端。
- 深度(Depth): 从根节点到某个节点的唯一路径的长度。
- 高度(Height): 从某个节点到其最远叶子节点的路径的长度。
二、常见类型:
二叉树(Binary Tree): 每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉搜索树(Binary Search Tree): 一种二叉树,左子树上的节点值小于根节点值,右子树上的节点值大于根节点值,且左右子树也都是二叉搜索树。
平衡二叉树(Balanced Binary Tree): 一种二叉搜索树,确保左右子树的高度差不超过 1,以保持树的平衡。
AVL 树: 一种自平衡二叉搜索树,通过旋转操作保持平衡。
B 树(B-tree): 一种多路搜索树,常用于文件系统和数据库的索引结构。
树状数组(Binary Indexed Tree): 用于高效处理数组的前缀和操作。
三、应用场景:
文件系统: 文件和目录的组织结构通常可以表示为树。
数据库索引: 数据库中的索引结构往往使用树的形式,例如 B 树和 B+ 树。
表达式树: 将数学表达式表示为树状结构,方便求值和优化。
网络路由表: 路由器使用树状结构表示网络的路由信息。
XML/JSON 解析: 在解析 XML 或 JSON 数据时,常常使用树状结构表示数据的层次关系。
编译器语法树: 在编译器中,源代码通常被表示为一棵语法树。
四、二叉搜索树(实例)
javascript
// 定义二叉树节点
class TreeNode {
constructor(value) {
this.value = value
this.left = null
this.right = null
}
}
// 定义二叉搜索树
class BinarySearchTree {
constructor() {
this.root = null
}
// 插入节点
insert(value) {
const newNode = new TreeNode(value)
if (this.root === null) {
this.root = newNode
} else {
this._insertRecursive(this.root, newNode)
}
}
_insertRecursive(root, newNode) {
if (newNode.value < root.value) {
if (root.left === null) {
root.left = newNode
} else {
this._insertRecursive(root.left, newNode)
}
} else {
if (root.right === null) {
root.right = newNode
} else {
this._insertRecursive(root.right, newNode)
}
}
}
// 查找节点
search(value) {
return this._searchRecursive(this.root, value)
}
_searchRecursive(root, value) {
if (root === null || root.value === value) {
return root
}
if (value < root.value) {
return this._searchRecursive(root.left, value)
} else {
return this._searchRecursive(root.right, value)
}
}
// 中序遍历
inOrderTraversal() {
const result = []
this._inOrderTraversalRecursive(this.root, result)
return result
}
_inOrderTraversalRecursive(root, result) {
if (root !== null) {
this._inOrderTraversalRecursive(root.left, result)
result.push(root.value)
this._inOrderTraversalRecursive(root.right, result)
}
}
}
// 示例使用
const bst = new BinarySearchTree()
bst.insert(10)
bst.insert(5)
bst.insert(15)
bst.insert(3)
bst.insert(7)
bst.insert(12)
bst.insert(18)
console.log('In-Order Traversal Result:', bst.inOrderTraversal())
// 输出: [3, 5, 7, 10, 12, 15, 18]
const searchResult = bst.search(7)
console.log('Search Result for 7:', searchResult)
// 输出: TreeNode { value: 7, left: TreeNode { ... }, right: TreeNode { ... } }
在这个例子中,我们创建了一个二叉搜索树,并依次插入了一些节点。然后,我们展示了中序遍历操作,它按照从小到大的顺序输出树中的节点值。最后,我们查找了树中值为 7 的节点,并输出了搜索结果。这个例子涵盖了二叉搜索树的插入、查找和遍历等基本操作。