二叉树
二叉树(Binary Tree)是树形数据结构的一种特殊形式,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树在计算机科学中有着广泛的应用,如表达式解析、排序算法和搜索算法等。
常见术语
- 节点(Node):树的基本单位,包含数据和指向子节点的指针。
- 边(Edge):连接两个节点的线段。
- 度(Degree):一个节点的子节点数。
- 根节点(Root Node):树的顶端节点,没有父节点。
- 叶节点(Leaf Node):没有子节点的节点。
- 父节点(Parent Node):具有子节点的节点。
- 子节点(Child Node):由另一个节点指向的节点。
- 节点高度(Node Height):从当前节点到叶节点的最长路径上的边数。
- 树的高度(Tree Height):树中节点的最大高度。
- 深度(Depth):从根节点到当前节点的路径上的边数。
- 完全二叉树(Complete Binary Tree):除最后一层外,每一层的所有节点都有两个子节点,最后一层的节点尽可能左对齐。
- 满二叉树(Full Binary Tree):所有非叶节点都有两个子节点,所有叶节点在同一层。
- 完美二叉树(Perfect Binary Tree):一个满二叉树,同时也是完全二叉树。
前序遍历、中序遍历和后序遍历的特点比较
遍历方式 | 访问顺序 | 特点 |
---|---|---|
前序遍历(Pre-order) | 根节点 -> 左子树 -> 右子树 | 先访问根节点,适合用于复制二叉树 |
中序遍历(In-order) | 左子树 -> 根节点 -> 右子树 | 中序遍历二叉搜索树可得到有序序列 |
后序遍历(Post-order) | 左子树 -> 右子树 -> 根节点 | 先访问子节点,适合用于删除二叉树 |
二叉树的基本操作
在二叉树中,常见的操作包括插入节点、查找节点、删除节点以及遍历节点(前序遍历、中序遍历、后序遍历)。另外,我们还需要计算树的高度和节点的高度。
下面是一个用Go语言实现的二叉树示例,包含基本的插入、遍历和计算高度操作。
Go语言实现二叉树
package main
import "fmt"
// 定义节点结构体
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
// 插入节点
func (n *TreeNode) Insert(value int) {
if n == nil {
return
} else if value <= n.Value {
if n.Left == nil {
n.Left = &TreeNode{Value: value}
} else {
n.Left.Insert(value)
}
} else {
if n.Right == nil {
n.Right = &TreeNode{Value: value}
} else {
n.Right.Insert(value)
}
}
}
// 前序遍历
func (n *TreeNode) PreOrderTraversal() {
if n == nil {
return
}
fmt.Printf("%d ", n.Value)
n.Left.PreOrderTraversal()
n.Right.PreOrderTraversal()
}
// 中序遍历
func (n *TreeNode) InOrderTraversal() {
if n == nil {
return
}
n.Left.InOrderTraversal()
fmt.Printf("%d ", n.Value)
n.Right.InOrderTraversal()
}
// 后序遍历
func (n *TreeNode) PostOrderTraversal() {
if n == nil {
return
}
n.Left.PostOrderTraversal()
n.Right.PostOrderTraversal()
fmt.Printf("%d ", n.Value)
}
// 计算节点高度
func (n *TreeNode) NodeHeight() int {
if n == nil {
return -1
}
leftHeight := n.Left.NodeHeight()
rightHeight := n.Right.NodeHeight()
if leftHeight > rightHeight {
return leftHeight + 1
}
return rightHeight + 1
}
// 计算树的高度
func (n *TreeNode) TreeHeight() int {
return n.NodeHeight()
}
func main() {
root := &TreeNode{Value: 10}
root.Insert(5)
root.Insert(15)
root.Insert(2)
root.Insert(7)
root.Insert(12)
root.Insert(20)
fmt.Println("前序遍历:")
root.PreOrderTraversal()
fmt.Println()
fmt.Println("中序遍历:")
root.InOrderTraversal()
fmt.Println()
fmt.Println("后序遍历:")
root.PostOrderTraversal()
fmt.Println()
fmt.Printf("树的高度: %d\n", root.TreeHeight())
}
代码解释
- 定义节点结构体:
TreeNode
结构体包含节点的值以及指向左子节点和右子节点的指针。 - 插入节点:
Insert
方法根据值的大小将新节点插入到二叉树的适当位置。 - 前序遍历:
PreOrderTraversal
方法先访问节点本身,然后递归遍历左子树和右子树。 - 中序遍历:
InOrderTraversal
方法先递归遍历左子树,然后访问节点本身,最后递归遍历右子树。 - 后序遍历:
PostOrderTraversal
方法先递归遍历左子树和右子树,最后访问节点本身。 - 计算节点高度:
NodeHeight
方法递归计算节点到其最远叶节点的路径长度。 - 计算树的高度:
TreeHeight
方法返回树的最大节点高度。
通过这些基本操作,我们可以构建、插入、查找和遍历二叉树,并计算树的高度。这些基本操作为我们在计算机科学中的各种应用打下了坚实的基础。