ZBLOG

go 语言根据下面定义实现红黑树, 并实现插入、删除、前种后序遍历 // 红黑树节点的颜色 const ( red bool = false black bool = true ) // Node 节点结构体 type Node struct { value interface{} // 节点值 color bool // 节点颜色 left *Node // 左子节点 right *Node // 右子节点 paren...

以下是红黑树的实现:

package red_black_tree

// 红黑树节点的颜色 const (

red   bool = false
black bool = true

)

// Node 节点结构体 type Node struct {

value  interface{} // 节点值
color  bool        // 节点颜色
left   *Node       // 左子节点
right  *Node       // 右子节点
parent *Node       // 父节点

}

// RBTree 红黑树结构体 type RBTree struct {

root *Node // 根节点

}

// NewRBTree 创建红黑树 func NewRBTree() *RBTree {

return &RBTree{}

}

// Insert 插入节点到红黑树中 func (t *RBTree) Insert(value interface{}) {

if t.root == nil {
    t.root = &Node{value: value, color: black}
    return
}

node := t.root
for {
    if node.value.(int) > value.(int) {
        if node.left == nil {
            node.left = &Node{value: value, parent: node, color: red}
            t.insertFixup(node.left)
            return
        }
        node = node.left
    } else {
        if node.right == nil {
            node.right = &Node{value: value, parent: node, color: red}
            t.insertFixup(node.right)
            return
        }
        node = node.right
    }
}

}

// insertFixup 插入节点修正,保持红黑树性质 func (t *RBTree) insertFixup(node *Node) {

for node.parent != nil && node.parent.color == red {
    if node.parent.parent != nil && node.parent == node.parent.parent.left {
        uncle := node.parent.parent.right
        if uncle != nil && uncle.color == red { // 情况1:父节点和叔叔节点都是红色
            node.parent.color = black
            uncle.color = black
            node.parent.parent.color = red
            node = node.parent.parent
        } else { // 情况2:父节点是红色,叔叔节点是黑色,并且新节点是父节点的右子节点
            if node == node.parent.right {
                node = node.parent
                t.rotateLeft(node)
            }
            // 情况3:父节点是红色,叔叔节点是黑色,并且新节点是父节点的左子节点
            node.parent.color = black
            node.parent.parent.color = red
            t.rotateRight(node.parent.parent)
        }
    } else {
        uncle := node.parent.parent.left
        if uncle != nil && uncle.color == red { // 情况1:父节点和叔叔节点都是红色
            node.parent.color = black
            uncle.color = black
            node.parent.parent.color = red
            node = node.parent.parent
        } else { // 情况2:父节点是红色,叔叔节点是黑色,并且新节点是父节点的左子节点
            if node == node.parent.left {
                node = node.parent
                t.rotateRight(node)
            }
            // 情况3:父节点是红色,叔叔节点是黑色,并且新节点是父节点的右子节点
            node.parent.color = black
            node.parent.parent.color = red
            t.rotateLeft(node.parent.parent)
        }
    }
}

t.root.color = black

}

// Delete 从红黑树中删除节点 func (t *RBTree) Delete(value interface{}) {

node := t.search(value)
if node == nil {
    return
}

if node.left != nil && node.right != nil {
    // 找到后继节点
    succ := node.right
    for succ.left != nil {
        succ = succ.left
    }
    node.value = succ.value
    node = succ
}

var child *Node
if node.left != nil {
    child = node.left
} else {
    child = node.right
}

if node.color == black {
    node.color = child.color
    t.deleteFixup(node)
}

if node.parent == nil {
    t.root = child
} else if node.parent.left == node {
    node.parent.left = child
} else {
    node.parent.right = child
}

if child != nil {
    child.parent = node.parent
}

}

// deleteFixup 删除节点修正,保持红黑树性质 func (t *RBTree) deleteFixup(node *Node) {

for node.parent != nil && node.color == black {
    if node == node.parent.left {
        sibling := node.parent.right
        if sibling.color == red { // 情况1:兄弟节点为红色
            sibling.color = black
            node.parent.color = red
            t.rotateLeft(node.parent)
            sibling = node.parent.right
        }
        if sibling.left.color == black && sibling.right.color == black { // 情况2:兄弟节点和其子节点均为黑色
            sibling.color = red
            node = node.parent
        } else {
            if sibling.right.color == black { // 情况3:兄弟节点是黑色,且其左子节点是红色,右子节点是黑色
                sibling.left.color = black
                sibling.color = red
                t.rotateRight(sibling)
                sibling = node.parent.right
            }
            // 情况4:兄弟节点是黑色,且其右子节点是红色
            sibling.color = node.parent.color
            node.parent.color = black
            sibling.right.color = black
            t.rotateLeft(node.parent)
            node = t.root
        }
    } else {
        sibling := node.parent.left
        if sibling.color == red { // 情况1:兄弟节点为红色
            sibling.color = black
            node.parent.color = red
            t.rotateRight(node.parent)
            sibling = node.parent.left
        }
        if sibling.left.color == black && sibling.right.color == black { // 情况2:兄弟节点和其子节点均为黑色
            sibling.color = red
            node = node.parent
        } else {
            if sibling.left.color == black { // 情况3:兄弟节点是黑色,且其右子节点是红色,左子节点是黑色
                sibling.right.color = black
                sibling.color = red
                t.rotateLeft(sibling)
                sibling = node.parent.left
            }
            // 情况4:兄弟节点是黑色,且其左子节点是红色
            sibling.color = node.parent.color
            node.parent.color = black
            sibling.left.color = black
            t.rotateRight(node.parent)
            node = t.root
        }
    }
}

node.color = black

}

// search 查找红黑树中的节点 func (t *RBTree) search(value interface{}) *Node {

node := t.root
for node != nil {
    if node.value.(int) == value.(int) {
        return node
    } else if node.value.(int) > value.(int) {
        node = node.left
    } else {
        node = node.right
    }
}
return nil

}

// rotateLeft 左旋操作 func (t *RBTree) rotateLeft(node *Node) {

right := node.right
node.right = right.left
if right.left != nil {
    right.left.parent = node
}
right.parent = node.parent
if node.parent == nil {
    t.root = right
} else if node == node.parent.left {
    node.parent.left = right
} else {
    node.parent.right = right
}
right.left = node
node.parent = right

}

// rotateRight 右旋操作 func (t *RBTree) rotateRight(node *Node) {

left := node.left
node.left = left.right
if left.right != nil {
    left.right.parent = node
}
left.parent = node.parent
if node.parent == nil {
    t.root = left
} else if node == node.parent.left {
    node.parent.left = left
} else {
    node.parent.right = left
}
left.right = node
node.parent = left

}

// PreOrderTraversal 前序遍历红黑树 func (t *RBTree) PreOrderTraversal() []interface{} {

if t.root == nil {
    return []interface{}{}
}

var result []interface{}
stack := []*Node{t.root}
for len(stack) > 0 {
    node := stack[len(stack)-1]
    stack = stack[:len(stack)-1]
    result = append(result, node.value)
    if node.right != nil {
        stack = append(stack, node.right)
    }
    if node.left != nil {
        stack = append(stack, node.left)
    }
}

return result

}

// InOrderTraversal 中序遍历红黑树 func (t *RBTree) InOrderTraversal() []interface{} {

if t.root == nil {
    return []interface{}{}
}

var result []interface{}
stack := []*Node{}
node := t.root
for node != nil || len(stack) > 0 {
    for node != nil {
        stack = append(stack, node)
        node = node.left
    }
    node = stack[len(stack)-1]
    stack = stack[:len(stack)-1]
    result = append(result, node.value)
    node = node.right
}

return result

}

// PostOrderTraversal 后序遍历红黑树 func (t *RBTree) PostOrderTraversal() []interface{} {

if t.root == nil {
    return []interface{}{}
}

var result []interface{}
stack := []*Node{t.root}
var lastVisited *Node
for len(stack) > 0 {
    node := stack[len(stack)-1]
    if (node.left == nil && node.right == nil) || (lastVisited != nil && (lastVisited == node.left || lastVisited == node.right)) {
        result = append(result, node.value)
        stack = stack[:len(stack)-1]
        lastVisited = node
    } else {
        if node.right != nil {
            stack = append(stack, node.right)
        }
        if node.left != nil {
            stack = append(stack, node.left)
        }
    }
}

return result

}

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=1642

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?