ZBLOG

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

由于红黑树的实现比较复杂,需要考虑很多情况,因此在这里只提供伪代码演示。

插入操作:

func (t *RBTree) Insert(value interface{}) {

  1. node := &Node{value: value, color: red}
  2. if t.root == nil {
  3. t.root = node
  4. } else {
  5. parent := t.root // 从根节点开始查找插入位置
  6. for {
  7. if node.value < parent.value {
  8. if parent.left == nil {
  9. parent.left = node
  10. node.parent = parent
  11. break
  12. }
  13. parent = parent.left
  14. } else {
  15. if parent.right == nil {
  16. parent.right = node
  17. node.parent = parent
  18. break
  19. }
  20. parent = parent.right
  21. }
  22. }
  23. t.insertFixup(node) // 插入后进行修复
  24. }

}

func (t *RBTree) insertFixup(node *Node) {

  1. for node.parent != nil && node.parent.color == red { // 父节点存在且为红色时继续修复
  2. if node.parent == node.parent.parent.left { // 父节点为祖父节点的左子节点
  3. uncle := node.parent.parent.right // 叔叔节点
  4. if uncle != nil && uncle.color == red { // Case 1: 叔叔节点为红色
  5. node.parent.color = black
  6. uncle.color = black
  7. node.parent.parent.color = red
  8. node = node.parent.parent
  9. } else { // Case 2/3: 叔叔节点为黑色
  10. if node == node.parent.right { // Case 2: 新节点为父节点的右子节点
  11. node = node.parent
  12. t.leftRotate(node)
  13. }
  14. // Case 3: 新节点为父节点的左子节点
  15. node.parent.color = black
  16. node.parent.parent.color = red
  17. t.rightRotate(node.parent.parent)
  18. }
  19. } else { // 父节点为祖父节点的右子节点,与上面类似但是左右反转
  20. uncle := node.parent.parent.left
  21. if uncle != nil && uncle.color == red {
  22. node.parent.color = black
  23. uncle.color = black
  24. node.parent.parent.color = red
  25. node = node.parent.parent
  26. } else {
  27. if node == node.parent.left {
  28. node = node.parent
  29. t.rightRotate(node)
  30. }
  31. node.parent.color = black
  32. node.parent.parent.color = red
  33. t.leftRotate(node.parent.parent)
  34. }
  35. }
  36. }
  37. t.root.color = black // 根节点总是黑色

}

删除操作:

func (t *RBTree) Delete(value interface{}) {

  1. node := t.searchNode(t.root, value)
  2. if node == nil {
  3. return
  4. }
  5. var child *Node
  6. var color bool
  7. if node.left == nil { // 左子树为空或只有一个右子节点
  8. child = node.right
  9. t.transplant(node, node.right)
  10. } else if node.right == nil { // 右子树为空或只有一个左子节点
  11. child = node.left
  12. t.transplant(node, node.left)
  13. } else { // 左右子树均不为空
  14. successor := t.minimumNode(node.right) // 找到右子树的最小节点
  15. color = successor.color
  16. child = successor.right
  17. if successor.parent == node { // 后继节点是待删除节点的右子节点
  18. child.parent = successor
  19. } else {
  20. t.transplant(successor, successor.right)
  21. successor.right = node.right
  22. successor.right.parent = successor
  23. }
  24. t.transplant(node, successor)
  25. successor.left = node.left
  26. successor.left.parent = successor
  27. successor.color = node.color
  28. }
  29. if color == black { // 如果删除的是黑色节点,则需要修复
  30. t.deleteFixup(child)
  31. }

}

func (t *RBTree) deleteFixup(node *Node) {

  1. for node != t.root && node.color == black {
  2. if node == node.parent.left { // 被删除节点为父节点的左子节点
  3. sibling := node.parent.right // 兄弟节点
  4. if sibling.color == red { // Case 1: 兄弟节点为红色
  5. sibling.color = black
  6. node.parent.color = red
  7. t.leftRotate(node.parent)
  8. sibling = node.parent.right
  9. }
  10. if sibling.left.color == black && sibling.right.color == black { // Case 2: 兄弟节点和兄弟节点的子节点均为黑色
  11. sibling.color = red
  12. node = node.parent
  13. } else {
  14. if sibling.right.color == black { // Case 3: 兄弟节点为黑色,兄弟节点的右子节点为黑色,兄弟节点的左子节点为红色
  15. sibling.left.color = black
  16. sibling.color = red
  17. t.rightRotate(sibling)
  18. sibling = node.parent.right
  19. }
  20. // Case 4: 兄弟节点为黑色,兄弟节点的右子节点为红色
  21. sibling.color = node.parent.color
  22. node.parent.color = black
  23. sibling.right.color = black
  24. t.leftRotate(node.parent)
  25. node = t.root // 跳出循环
  26. }
  27. } else { // 被删除节点为父节点的右子节点,与上面类似但是左右反转
  28. sibling := node.parent.left
  29. if sibling.color == red {
  30. sibling.color = black
  31. node.parent.color = red
  32. t.rightRotate(node.parent)
  33. sibling = node.parent.left
  34. }
  35. if sibling.left.color == black && sibling.right.color == black {
  36. sibling.color = red
  37. node = node.parent
  38. } else {
  39. if sibling.left.color == black {
  40. sibling.right.color = black
  41. sibling.color = red
  42. t.leftRotate(sibling)
  43. sibling = node.parent.left
  44. }
  45. sibling.color = node.parent.color
  46. node.parent.color = black
  47. sibling.left.color = black
  48. t.rightRotate(node.parent)
  49. node = t.root
  50. }
  51. }
  52. }
  53. node.color = black

}

前序遍历:

func (t *RBTree) PreorderTraversal() []interface{} {

  1. var values []interface{}
  2. var preorder func(node *Node)
  3. preorder = func(node *Node) {
  4. if node != nil {
  5. values = append(values, node.value)
  6. preorder(node.left)
  7. preorder(node.right)
  8. }
  9. }
  10. preorder(t.root)
  11. return values

}

中序遍历:

func (t *RBTree) InorderTraversal() []interface{} {

  1. var values []interface{}
  2. var inorder func(node *Node)
  3. inorder = func(node *Node) {
  4. if node != nil {
  5. inorder(node.left)
  6. values = append(values, node.value)
  7. inorder(node.right)
  8. }
  9. }
  10. inorder(t.root)
  11. return values

}

后序遍历:

func (t *RBTree) PostorderTraversal() []interface{} {

  1. var values []interface{}
  2. var postorder func(node *Node)
  3. postorder = func(node *Node) {
  4. if node != nil {
  5. postorder(node.left)
  6. postorder(node.right)
  7. values = append(values, node.value)
  8. }
  9. }
  10. postorder(t.root)
  11. return values

}

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?