package main
//定义常量红黑
const (
RED = true
BLACK = false
)
//红黑树结构
type RBNode struct {
Left *RBNode //左节点
Right *RBNode //右边节点
Parent *RBNode //父亲节点
Color bool //颜色
//DataItem interface{} //数据
Item //数据接口
}
//数据接口
type Item interface {
Less(than Item) bool
}
//红黑树
type RBtree struct {
NIL *RBNode
Root *RBNode
count uint
}
//比大小
func less(x, y Item) bool {
return x.Less(y)
}
//初始化内存
func NewRBTree() *RBtree {
return new(RBtree).Init()
}
//初始化红黑树
func (rbt *RBtree) Init() *RBtree {
node := &RBNode{nil, nil, nil, BLACK, nil}
return &RBtree{node, node, 0}
}
//获取红黑树长度
func (rbt *RBtree) Len() uint {
return rbt.count
}
//取得红黑树的极大值节点
func (rbt *RBtree) max(x *RBNode) *RBNode {
if x == rbt.NIL {
return rbt.NIL
}
for x.Right != rbt.NIL {
x = x.Right
}
return x
}
//取得红黑树的极小值
func (rbt *RBtree) min(x *RBNode) *RBNode {
if x == rbt.NIL {
return rbt.NIL
}
for x.Left != rbt.NIL {
x = x.Left
}
return x
}
//搜索红黑树
func (rbt *RBtree) search(x *RBNode) *RBNode {
pnode := rbt.Root //根节点
for pnode != rbt.NIL {
if less(pnode.Item, x.Item) {
pnode = pnode.Right
} else if less(x.Item, pnode.Item) {
pnode = pnode.Left
} else {
break //找到
}
}
return pnode
}
func (rbt *RBtree) leftRotate(x *RBNode) {
if x.Right == rbt.NIL {
return //左旋转,逆时针,右孩子不可以为0
}
y := x.Right
x.Right = y.Left //实现旋转的左旋
if y.Left != rbt.NIL {
y.Left.Parent = x //设定父亲节点
}
y.Parent = x.Parent //传递父节点
if x.Parent == rbt.NIL {
//根节点
rbt.Root = y
} else if x == x.Parent.Left { //x在根节点左边
x.Parent.Left = y
} else { //x在根节点右边
x.Parent.Right = y
}
y.Left = x
x.Parent = y
}
func (rbt *RBtree) rightRotate(x *RBNode) {
if x.Left == nil {
return //右边旋转,左子树不可以为空
}
y := x.Left
x.Left = y.Right
if y.Right != rbt.NIL {
y.Right.Parent = x //设置祖先
}
y.Parent = x.Parent //y保存x的父亲节点
if x.Parent == rbt.NIL {
rbt.Root = y
} else if x == x.Parent.Left { //x小于根节点
x.Parent.Left = y //父亲节点的孩子是x,改。父亲节点孩子y
} else { //x大于根节点
x.Parent.Right = y
}
y.Right = x
x.Parent = y
}
//插入一条数据
func (rbt *RBtree) Insert(item Item) *RBNode {
if item == nil {
return nil
}
return rbt.insert(&RBNode{rbt.NIL, rbt.NIL, rbt.NIL, RED, item})
}
//插入
func (rbt *RBtree) insert(z *RBNode) *RBNode {
//寻找插入位置
x := rbt.Root
y := rbt.NIL
for x != rbt.NIL {
y = x //备份位置,数据插入x,y之间
if less(z.Item, x.Item) { //小于
x = x.Left
} else if less(x.Item, z.Item) { //大于
x = x.Right
} else { //相等
return x //数据已经存在,无法插入
}
}
z.Parent = y
if y == rbt.NIL {
rbt.Root = z
} else if less(z.Item, y.Item) {
y.Left = z //小于左边插入
} else {
y.Right = z //大于右边插入
}
rbt.count++
rbt.insertFixup(z) //调整平衡
return z
}
//插入之后,调整平衡
func (rbt *RBtree) insertFixup(z *RBNode) {
for z.Parent.Color == RED { //一直循环下去,直到根节点
if z.Parent == z.Parent.Parent.Left { //父亲节点在爷爷左边
y := z.Parent.Parent.Right
if 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 = z.Parent
rbt.leftRotate(z) //左旋
} else { //z比父亲大
z.Parent.Color = BLACK
z.Parent.Parent.Color = RED
rbt.rightRotate(z.Parent.Parent)
}
}
} else { // //父亲节点在爷爷右边
y := z.Parent.Parent.Left //叔叔节点
if 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
rbt.rightRotate(z)
} else {
z.Parent.Color = BLACK
z.Parent.Parent.Color = RED
rbt.leftRotate(z.Parent.Parent)
}
}
}
}
rbt.Root.Color = BLACK
}
func (rbt *RBtree) GetDepth() int {
var getDeepth func(node *RBNode) int //函数
//函数包含
getDeepth = func(node *RBNode) int {
if node == nil {
return 0
}
if node.Left == nil && node.Right == nil {
return 1
}
var leftdeep int = getDeepth(node.Left)
var rightdeep int = getDeepth(node.Right)
if leftdeep > rightdeep {
return leftdeep + 1
} else {
return rightdeep + 1
}
}
return getDeepth(rbt.Root)
}
//近似查找
func (rbt *RBtree) searchle(x *RBNode) *RBNode {
p := rbt.Root //根节点
n := p //备份根节点
for n != rbt.NIL {
if less(n.Item, x.Item) {
p = n
n = n.Right //大于
} else if less(x.Item, n.Item) {
p = n
n = n.Left //小于
} else {
return n
break //跳出循环
}
}
if less(p.Item, x.Item) {
return p
}
p = rbt.desuccessor(p) //近似处理
return p
}
func (rbt *RBtree) successor(x *RBNode) *RBNode {
if x == rbt.NIL {
return rbt.NIL
}
if x.Right != rbt.NIL {
return rbt.min(x.Right) //取得右边最小
}
y := x.Parent
for y != rbt.NIL && x == y.Right {
x = y
y = y.Parent
}
return y
}
func (rbt *RBtree) desuccessor(x *RBNode) *RBNode {
if x == rbt.NIL {
return rbt.NIL
}
if x.Left != rbt.NIL {
return rbt.max(x.Left) //取得左边最大
}
y := x.Parent
for y != rbt.NIL && x == y.Left {
x = y
y = y.Parent
}
return y
}
//最小,最大,查找,修改,近似查找
func (rbt *RBtree) Delete(item Item) Item {
if item == nil {
return nil
}
return rbt.delete(&RBNode{rbt.NIL, rbt.NIL, rbt.NIL, RED, item}).Item
}
func (rbt *RBtree) delete(key *RBNode) *RBNode {
z := rbt.search(key) //寻找要删除的节点
if z == rbt.NIL {
return rbt.NIL //无需删除
}
//新建节点下,x,y备份,夹逼
var x *RBNode
var y *RBNode
//节点
ret := &RBNode{rbt.NIL, rbt.NIL, rbt.NIL, z.Color, z.Item}
if z.Left == rbt.NIL || z.Right == rbt.NIL {
y = z //单节点,y,z重合
} else {
y = rbt.successor(z) //找到最接近的右边最小
}
if y.Left != rbt.NIL {
x = y.Left
} else {
x = y.Right
}
x.Parent = y.Parent
if y.Parent == rbt.NIL {
rbt.Root = x
} else if y == y.Parent.Left {
y.Parent.Left = x
} else {
y.Parent.Right = x
}
if y != z {
z.Item = y.Item
}
if y.Color == BLACK {
rbt.deleteFixup(x)
}
rbt.count--
return ret
}
//删除时的红黑修复需要考虑四种情况(下面的“X”指取代了被删节点位置的新节点)
// (1) X的兄弟节点是红色的:
// | |
// 1● 3●
// / \ --------\ / \
// X-> 2● ○3 <-brother --------/ 1○ ●5
// / \ / \
// 4● ●5 X-> 2● ●4
//
// (2) X的兄弟节点是黑色的,而且兄弟节点的两个孩子都是黑色的:
// | |
// 1○ X-> 1○
// / \ --------\ / \
// X-> 2● ●3 <-brother --------/ 2● ○3
// / \ / \
// 4● ●5 4● ●5
//
// (3) X的兄弟节点是黑色的,兄弟的左孩子是红色的,右孩子是黑色的:
// | |
// 1○ 1○
// / \ --------\ / \
// X-> 2● ●3 <-brother --------/ X->2● ●4
// / \ \
// 4○ ●5 ○3
// \
// ●5
//
// (4) X的兄弟节点是黑色的,兄弟的右孩子是红色的:
// | |
// 1○ 3○ X->root and loop while end
// / \ --------\ / \
// X-> 2● ●3 <-brother --------/ 1● ●5
// / \ / \
// 4○ ○5 2● ○4
//
//以上是兄弟节点在X右边时的情况,在X左边是取相反即可!
func (rbt *RBtree) deleteFixup(x *RBNode) {
for x != rbt.Root && x.Color == BLACK {
if x == x.Parent.Left { //x在左边
w := x.Parent.Right //哥哥节点
if w.Color == RED { //左边旋转
w.Color = BLACK
x.Parent.Color = RED
rbt.leftRotate(x.Parent)
w = x.Parent.Right //循环步骤
}
if w.Left.Color == BLACK && w.Right.Color == BLACK {
w.Color = RED
x = x.Parent //循环条件
} else {
if w.Right.Color == BLACK {
w.Left.Color = BLACK
w.Color = RED
rbt.rightRotate(w) //右旋转
w = x.Parent.Right //循环条件
}
w.Color = x.Parent.Color
x.Parent.Color = BLACK
w.Right.Color = BLACK
rbt.leftRotate(x.Parent)
x = rbt.Root
}
} else { //x在右边
w := x.Parent.Left //左边节点
if w.Color == RED { //左旋
w.Color = BLACK
x.Parent.Color = RED
rbt.rightRotate(x.Parent)
w = x.Parent.Right //循环步骤
}
if w.Left.Color == BLACK && w.Right.Color == BLACK {
w.Color = RED
x = x.Parent //循环条件
} else {
if w.Right.Color == BLACK {
w.Left.Color = BLACK
w.Color = RED
rbt.leftRotate(w) //右旋转
w = x.Parent.Left //循环条件
}
w.Color = x.Parent.Color
x.Parent.Color = BLACK
w.Right.Color = BLACK
rbt.rightRotate(x.Parent)
x = rbt.Root
}
}
}
x.Color = BLACK //循环到最后根节点,黑色
}