二元樹是電腦科學中一種重要的資料結構,它在許多應用領域中都有廣泛的用途。本文將介紹二元樹的概念、性質、常見型別和應用。
二元樹(Binary Tree)是一種樹形資料結構,它由節點構成,每個節點最多有兩個子節點,通常稱為左子節點和右子節點。這兩個子節點可以為空,也可以包含資料或值。二元樹是一種層次結構,根節點位於樹的頂部,其他節點按照層級依次排列。
二元樹具有許多重要的性質,包括:
二元樹有許多不同型別的變體,其中一些最常見的包括:
以下是一個簡單的Go語言實現的二元搜尋樹(Binary Search Tree,BST)範例。這個範例包括二元搜尋樹的基本操作,如插入、查詢和中序遍歷。
package main
import "fmt"
// TreeNode 表示二元搜尋樹的節點結構
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
// Insert 用於向BST中插入新的節點
func (root *TreeNode) Insert(value int) *TreeNode {
if root == nil {
return &TreeNode{Value: value}
}
if value < root.Value {
root.Left = root.Left.Insert(value)
} else if value > root.Value {
root.Right = root.Right.Insert(value)
}
return root
}
// Search 用於在BST中搜尋特定值
func (root *TreeNode) Search(value int) *TreeNode {
if root == nil || root.Value == value {
return root
}
if value < root.Value {
return root.Left.Search(value)
}
return root.Right.Search(value)
}
// InorderTraversal 用於執行中序遍歷BST
func (root *TreeNode) InorderTraversal() {
if root != nil {
root.Left.InorderTraversal()
fmt.Printf("%d ", root.Value)
root.Right.InorderTraversal()
}
}
func main() {
root := &TreeNode{Value: 10}
root.Insert(5)
root.Insert(15)
root.Insert(3)
root.Insert(7)
root.Insert(12)
root.Insert(18)
fmt.Println("Inorder Traversal of BST:")
root.InorderTraversal()
fmt.Println()
searchValue := 7
if root.Search(searchValue) != nil {
fmt.Printf("Found %d in BST.\n", searchValue)
} else {
fmt.Printf("%d not found in BST.\n", searchValue)
}
searchValue = 8
if root.Search(searchValue) != nil {
fmt.Printf("Found %d in BST.\n", searchValue)
} else {
fmt.Printf("%d not found in BST.\n", searchValue)
}
}
在這個範例中,我們定義了一個TreeNode
結構來表示BST的節點,以及用於插入和搜尋節點的方法。我們還實現了中序遍歷以演示BST中元素的有序輸出。在main
函數中,我們建立了一個BST,插入了一些值,然後進行了搜尋操作並進行了中序遍歷。
平衡二元樹(Balanced Binary Tree)是一種特殊型別的二元樹,它的高度保持在較小範圍內,以確保樹的效能在搜尋、插入和刪除操作上都很好。其中一個常見的平衡二元樹是AVL樹。以下是一個用Go語言實現的簡單AVL樹範例:
package main
import (
"fmt"
)
type TreeNode struct {
Value int
Left, Right *TreeNode
Height int
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func height(node *TreeNode) int {
if node == nil {
return -1
}
return node.Height
}
func updateHeight(node *TreeNode) {
node.Height = 1 + max(height(node.Left), height(node.Right))
}
func rotateRight(y *TreeNode) *TreeNode {
x := y.Left
T2 := x.Right
x.Right = y
y.Left = T2
updateHeight(y)
updateHeight(x)
return x
}
func rotateLeft(x *TreeNode) *TreeNode {
y := x.Right
T2 := y.Left
y.Left = x
x.Right = T2
updateHeight(x)
updateHeight(y)
return y
}
func getBalance(node *TreeNode) int {
if node == nil {
return 0
}
return height(node.Left) - height(node.Right)
}
func insert(root *TreeNode, value int) *TreeNode {
if root == nil {
return &TreeNode{Value: value, Height: 1}
}
if value < root.Value {
root.Left = insert(root.Left, value)
} else if value > root.Value {
root.Right = insert(root.Right, value)
} else {
// Duplicate values are not allowed
return root
}
updateHeight(root)
balance := getBalance(root)
// Left-Left case
if balance > 1 && value < root.Left.Value {
return rotateRight(root)
}
// Right-Right case
if balance < -1 && value > root.Right.Value {
return rotateLeft(root)
}
// Left-Right case
if balance > 1 && value > root.Left.Value {
root.Left = rotateLeft(root.Left)
return rotateRight(root)
}
// Right-Left case
if balance < -1 && value < root.Right.Value {
root.Right = rotateRight(root.Right)
return rotateLeft(root)
}
return root
}
func inorderTraversal(root *TreeNode) {
if root != nil {
inorderTraversal(root.Left)
fmt.Printf("%d ", root.Value)
inorderTraversal(root.Right)
}
}
func main() {
var root *TreeNode
values := []int{10, 5, 15, 3, 7, 12, 18}
for _, value := range values {
root = insert(root, value)
}
fmt.Println("Inorder Traversal of AVL Tree:")
inorderTraversal(root)
fmt.Println()
}
在這個範例中,我們定義了一個TreeNode
結構來表示AVL樹的節點,包括值、左子樹、右子樹和高度。我們還實現了插入操作,以確保樹的平衡性。在main
函數中,我們建立了一個AVL樹,插入了一些值,然後進行了中序遍歷以顯示樹的元素按升序排列。
滿二元樹(Full Binary Tree)作為一種特殊型別的二元樹,每個節點都有0或2個子節點,而且葉子節點都位於同一層。以下是一個用Go語言實現的滿二元樹範例:
package main
import (
"fmt"
)
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
func NewTreeNode(value int) *TreeNode {
return &TreeNode{Value: value}
}
func main() {
root := NewTreeNode(1)
root.Left = NewTreeNode(2)
root.Right = NewTreeNode(3)
root.Left.Left = NewTreeNode(4)
root.Left.Right = NewTreeNode(5)
root.Right.Left = NewTreeNode(6)
root.Right.Right = NewTreeNode(7)
fmt.Println("Inorder Traversal of Full Binary Tree:")
inorderTraversal(root)
fmt.Println()
}
func inorderTraversal(root *TreeNode) {
if root != nil {
inorderTraversal(root.Left)
fmt.Printf("%d ", root.Value)
inorderTraversal(root.Right)
}
}
在這個範例中,我們定義了一個TreeNode
結構來表示滿二元樹的節點,包括值、左子樹和右子樹。在main
函數中,我們手動構建了一個滿二元樹,並執行了中序遍歷以顯示樹的元素。請注意,滿二元樹的特點是每個節點都有0或2個子節點,並且葉子節點都在同一層。這使得滿二元樹在某些應用中具有特殊的優勢。
以下是一個用Go語言實現的完全二元樹範例。在完全二元樹中,除了最後一層,其他層都是滿的,最後一層的節點從左向右填充。
package main
import (
"fmt"
)
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
func NewTreeNode(value int) *TreeNode {
return &TreeNode{Value: value}
}
func main() {
root := NewTreeNode(1)
root.Left = NewTreeNode(2)
root.Right = NewTreeNode(3)
root.Left.Left = NewTreeNode(4)
root.Left.Right = NewTreeNode(5)
root.Right.Left = NewTreeNode(6)
fmt.Println("Inorder Traversal of Complete Binary Tree:")
inorderTraversal(root)
fmt.Println()
}
func inorderTraversal(root *TreeNode) {
if root != nil {
inorderTraversal(root.Left)
fmt.Printf("%d ", root.Value)
inorderTraversal(root.Right)
}
}
在這個範例中,我們定義了一個TreeNode
結構來表示完全二元樹的節點,包括值、左子樹和右子樹。在main
函數中,我們手動構建了一個完全二元樹,並執行了中序遍歷以顯示樹的元素。請注意,完全二元樹的特點是除了最後一層,其他層都是滿的,最後一層的節點從左向右填充。這種結構在一些應用中具有特殊的性質,例如在堆資料結構中的應用。
二元樹在電腦科學和程式設計中有廣泛的應用,包括:
二元樹的遍歷是一種常見的操作,用於存取樹中的所有節點。主要的遍歷方法包括:
二元樹的遍歷是許多樹操作的基礎,它們可以用於搜尋、資料提取、樹的複製等任務。
宣告:本作品採用署名-非商業性使用-相同方式共用 4.0 國際 (CC BY-NC-SA 4.0)進行許可,使用時請註明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意