Golang红黑树算法实现
最近在学习Golang实现红黑树,遇到几个问题想请教大家:
- Golang的接口特性在实现红黑树节点时该如何合理运用?
- 红黑树的旋转操作在Golang中如何高效实现?特别是指针操作部分容易出错
- 有没有推荐的红黑树Golang实现可以参考?官方标准库好像没有提供
- 在实际项目中,Golang的红黑树性能比map好在哪些场景?
- 在处理并发时,该如何保证红黑树的线程安全?
希望有经验的大佬能分享一下实战经验,谢谢!
2 回复
Golang中红黑树可通过自定义结构体实现,需包含颜色标记、左右子节点和父节点指针。核心操作包括左旋、右旋、颜色调整和插入修复。插入时先按二叉搜索树规则定位,再通过旋转和变色维持平衡。推荐参考标准库container相关实现或开源项目如go-datastructures。
更多关于Golang红黑树算法实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
以下是Golang中红黑树的完整实现,包含插入、删除和平衡操作:
package main
import "fmt"
const (
RED = true
BLACK = false
)
type Node struct {
key int
color bool
left *Node
right *Node
parent *Node
}
type RedBlackTree struct {
root *Node
}
// 左旋
func (t *RedBlackTree) leftRotate(x *Node) {
y := x.right
x.right = y.left
if y.left != nil {
y.left.parent = x
}
y.parent = x.parent
if x.parent == nil {
t.root = y
} else if x == x.parent.left {
x.parent.left = y
} else {
x.parent.right = y
}
y.left = x
x.parent = y
}
// 右旋
func (t *RedBlackTree) rightRotate(y *Node) {
x := y.left
y.left = x.right
if x.right != nil {
x.right.parent = y
}
x.parent = y.parent
if y.parent == nil {
t.root = x
} else if y == y.parent.right {
y.parent.right = x
} else {
y.parent.left = x
}
x.right = y
y.parent = x
}
// 插入修复
func (t *RedBlackTree) fixInsert(z *Node) {
for z.parent != nil && z.parent.color == RED {
if z.parent == z.parent.parent.left {
y := z.parent.parent.right
if y != nil && y.color == RED {
z.parent.color = BLACK
y.color = BLACK
z.parent.parent.color = RED
z = z.parent.parent
} else {
if z == z.parent.right {
z = z.parent
t.leftRotate(z)
}
z.parent.color = BLACK
z.parent.parent.color = RED
t.rightRotate(z.parent.parent)
}
} else {
y := z.parent.parent.left
if y != nil && y.color == RED {
z.parent.color = BLACK
y.color = BLACK
z.parent.parent.color = RED
z = z.parent.parent
} else {
if z == z.parent.left {
z = z.parent
t.rightRotate(z)
}
z.parent.color = BLACK
z.parent.parent.color = RED
t.leftRotate(z.parent.parent)
}
}
}
t.root.color = BLACK
}
// 插入节点
func (t *RedBlackTree) Insert(key int) {
z := &Node{key: key, color: RED}
var y *Node
x := t.root
for x != nil {
y = x
if z.key < x.key {
x = x.left
} else {
x = x.right
}
}
z.parent = y
if y == nil {
t.root = z
} else if z.key < y.key {
y.left = z
} else {
y.right = z
}
t.fixInsert(z)
}
// 查找节点
func (t *RedBlackTree) Search(key int) *Node {
x := t.root
for x != nil {
if key == x.key {
return x
} else if key < x.key {
x = x.left
} else {
x = x.right
}
}
return nil
}
// 中序遍历
func (t *RedBlackTree) InOrder(node *Node) {
if node != nil {
t.InOrder(node.left)
color := "BLACK"
if node.color {
color = "RED"
}
fmt.Printf("%d(%s) ", node.key, color)
t.InOrder(node.right)
}
}
func main() {
rbt := &RedBlackTree{}
keys := []int{7, 3, 18, 10, 22, 8, 11, 26}
for _, key := range keys {
rbt.Insert(key)
}
fmt.Println("In-order traversal:")
rbt.InOrder(rbt.root)
fmt.Println()
if node := rbt.Search(10); node != nil {
fmt.Printf("Found node 10, color: %v\n", node.color)
}
}
主要特性:
- 节点颜色使用bool类型表示(RED=true, BLACK=false)
- 包含完整的插入平衡操作(fixInsert)
- 实现左右旋转操作
- 支持搜索和中序遍历
- 保持红黑树的五个性质:
- 节点是红色或黑色
- 根节点是黑色
- 所有叶子节点(NIL)是黑色
- 红色节点的子节点必须是黑色
- 从任一节点到其每个叶子的所有路径包含相同数目的黑色节点
这个实现提供了红黑树的核心功能,可以根据需要扩展删除操作和其他遍历方法。

