package main
import (
"fmt"
"sync"
)
//golang 红黑树
//只是实现了添加节点和一个分层打印节点的函数
//ref: https://www.jianshu.com/p/e136ec79235c
const (
Red = 1
Black = 2
)
type node struct {
right *node
left *node
parent *node
key int
color int
}
type RBTree struct {
root *node
//the number of members
len int
}
//add operation occured only on leaf
//so just ignore the parent's original son node
//color of the added node is always red
func (n *node) addLeft(key int) *node {
add := new(node)
add.key = key
add.color = Red
add.parent = n
n.left = add
return add
}
//add operation occured only on leaf
//so just ignore the parent's original son node
//color of the added node is always red
func (n *node) addRight(key int) *node {
add := new(node)
add.key = key
add.color = Red
add.parent = n
n.right = add
return add
}
func (rb *RBTree) rotateLeft(n *node) {
parent := n.parent
right := n.right
n.right = right.left
if right.left != nil {
right.left.parent = n
}
right.left = n
n.parent = right
if parent == nil {
right.parent = nil
rb.root = right
} else {
if n == parent.left {
parent.left = right
} else {
parent.right = right
}
right.parent = parent
}
}
func (rb *RBTree) rotateRight(n *node) {
parent := n.parent
left := n.left
n.left = left.right
if left.right != nil {
left.right.parent = n
}
left.right = n
n.parent = left
if parent == nil {
left.parent = nil
rb.root = left
} else {
if n == parent.left {
parent.left = left
} else {
parent.right = left
}
left.parent = parent
}
}
func (rb *RBTree) insert(key int) {
if rb.root == nil {
rb.root = new(node)
rb.root.key = key
rb.root.color = Black
} else {
p, ok := rb.find(key)
if ok {
//todo replace node value
return
}
//here p must not be nil
if p.key > key {
add := p.addLeft(key)
rb.ajustAdd(add)
} else {
add := p.addRight(key)
rb.ajustAdd(add)
}
}
rb.len++
}
func (rb *RBTree) ajustAdd(add *node) {
t := add
p := add.parent
for p != nil && p.color != Black {
//pp must not be nil because p is red
pp := p.parent
// get uncle
uncle := pp.left
if pp.left == p {
uncle = pp.right
}
if uncle == nil || uncle.color == Black {
if p == pp.left {
if t == p.right {
rb.rotateLeft(p)
}
rb.rotateRight(pp)
} else {
if t == p.left {
rb.rotateRight(p)
}
rb.rotateLeft(pp)
}
pp.color = Red
pp.parent.color = Black
break
} else {
// uncle must be red
p.color = Black
uncle.color = Black
pp.color = Red
t = pp
p = t.parent
}
}
if p == nil {
rb.root = t
rb.root.color = Black
rb.root.parent = nil
}
}
//if the second parameter return true,it indicates found
//else return the parent node that the key will be added
func (rb *RBTree) find(key int) (*node, bool) {
if rb.root == nil {
return nil, false
}
c := rb.root
p := c
for c != nil {
if c.key > key {
p = c
c = c.left
} else if c.key < key {
p = c
c = c.right
} else {
return c, true
}
}
return p, false
}
//just for debug
func (rb *RBTree)print() {
ch := make(chan interface{}, 1000)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
var dealed int
for {
select {
case v := <-ch:
if n, ok := v.(*node); ok {
if n == nil {
continue
}
dealed++
color := "red"
if n.color == Black {
color = "black"
}
pos := ""
if n.parent == nil {
pos = "root"
} else if n == n.parent.left {
pos = "left"
} else if n == n.parent.right {
pos = "right"
}
if n.parent != nil {
fmt.Printf(" %d(p %d,c %s,p %s)", n.key, n.parent.key, color, pos)
} else {
fmt.Printf(" %d(p %s,c %s,p %s)", n.key, "", color, pos)
}
ch <- n.left
ch <- n.right
} else {
fmt.Println()
if dealed == rb.len {
return
}
ch <- "next"
}
}
}
}()
ch <- rb.root
ch <- "next"
wg.Wait()
}
func main() {
rb := new(RBTree)
rb.insert(1)
rb.insert(2)
rb.insert(3)
rb.insert(4)
rb.insert(5)
rb.insert(6)
rb.insert(7)
rb.insert(8)
rb.insert(9)
rb.insert(10)
rb.insert(11)
rb.insert(12)
rb.insert(13)
rb.print()
}