找回密码
 立即注册
查看: 368|回复: 0

[其它] AVL树/红黑树实现及map与set的封装

[复制链接]

279

主题

0

回帖

964

积分

超级版主

积分
964
发表于 2024-6-23 12:19:04 | 显示全部楼层 |阅读模式
本帖最后由 Shaw0xyz 于 2024-6-23 15:47 编辑

1. 引言

在计算机科学中,平衡二叉搜索树(BST)是一种保持树的高度接近最小以确保操作高效的数据结构。常见的平衡二叉搜索树有AVL树和红黑树。本文将详细介绍AVL树和红黑树的实现,并讨论如何将它们封装成map和set数据结构。

1.1 AVL树

AVL树是一种自平衡二叉搜索树,每个节点维护一个平衡因子,即其左右子树的高度差。AVL树通过旋转操作保持平衡,以确保插入、删除和查找操作的时间复杂度为O(log n)。

1.1.1 AVL树的基本操作

AVL树的基本操作包括插入、删除和查找。在插入和删除节点后,AVL树需要进行平衡操作。

(1) 插入操作

插入节点后,如果树失去平衡,需要通过单旋转或双旋转恢复平衡。

示例代码:

  1. type AVLNode struct {
  2.     key    int
  3.     height int
  4.     left   *AVLNode
  5.     right  *AVLNode
  6. }

  7. func height(node *AVLNode) int {
  8.     if node == nil {
  9.         return 0
  10.     }
  11.     return node.height
  12. }

  13. func max(a, b int) int {
  14.     if a > b {
  15.         return a
  16.     }
  17.     return b
  18. }

  19. func rightRotate(y *AVLNode) *AVLNode {
  20.     x := y.left
  21.     T2 := x.right

  22.     x.right = y
  23.     y.left = T2

  24.     y.height = max(height(y.left), height(y.right)) + 1
  25.     x.height = max(height(x.left), height(x.right)) + 1

  26.     return x
  27. }

  28. func leftRotate(x *AVLNode) *AVLNode {
  29.     y := x.right
  30.     T2 := y.left

  31.     y.left = x
  32.     x.right = T2

  33.     x.height = max(height(x.left), height(x.right)) + 1
  34.     y.height = max(height(y.left), height(y.right)) + 1

  35.     return y
  36. }

  37. func getBalance(node *AVLNode) int {
  38.     if node == nil {
  39.         return 0
  40.     }
  41.     return height(node.left) - height(node.right)
  42. }

  43. func insert(node *AVLNode, key int) *AVLNode {
  44.     if node == nil {
  45.         return &AVLNode{key: key, height: 1}
  46.     }
  47.     if key < node.key {
  48.         node.left = insert(node.left, key)
  49.     } else if key > node.key {
  50.         node.right = insert(node.right, key)
  51.     } else {
  52.         return node
  53.     }

  54.     node.height = 1 + max(height(node.left), height(node.right))

  55.     balance := getBalance(node)

  56.     if balance > 1 && key < node.left.key {
  57.         return rightRotate(node)
  58.     }

  59.     if balance < -1 && key > node.right.key {
  60.         return leftRotate(node)
  61.     }

  62.     if balance > 1 && key > node.left.key {
  63.         node.left = leftRotate(node.left)
  64.         return rightRotate(node)
  65.     }

  66.     if balance < -1 && key < node.right.key {
  67.         node.right = rightRotate(node.right)
  68.         return leftRotate(node)
  69.     }

  70.     return node
  71. }
复制代码


(2) 删除操作

删除节点后,同样需要进行旋转操作以保持平衡。

1.1.2 AVL树的查找操作

查找操作与普通二叉搜索树相同,通过比较节点值递归或迭代进行查找。

示例代码:

  1. func search(node *AVLNode, key int) *AVLNode {
  2.     if node == nil || node.key == key {
  3.         return node
  4.     }
  5.     if key < node.key {
  6.         return search(node.left, key)
  7.     }
  8.     return search(node.right, key)
  9. }
复制代码


1.2 红黑树

红黑树是一种自平衡二叉搜索树,确保在插入和删除操作后保持近似平衡。红黑树通过颜色属性和旋转操作来保持平衡,插入和删除的时间复杂度为O(log n)。

1.2.1 红黑树的基本操作

红黑树的基本操作包括插入、删除和查找。

(1) 插入操作

插入节点后,通过重新着色和旋转操作恢复红黑树的性质。

(2) 删除操作

删除节点后,通过重新着色和旋转操作保持平衡。

1.2.2 红黑树的查找操作

查找操作与普通二叉搜索树相同,通过比较节点值递归或迭代进行查找。

1.3 map和set的封装

通过AVL树或红黑树实现map和set数据结构,可以确保键的有序性和操作的高效性。

1.3.1 map的实现

map是一种键值对数据结构,可以通过AVL树或红黑树实现。每个节点存储一个键值对,支持插入、删除和查找操作。

示例代码:

  1. type MapNode struct {
  2.     key    int
  3.     value  interface{}
  4.     height int
  5.     left   *MapNode
  6.     right  *MapNode
  7. }

  8. func insertMapNode(node *MapNode, key int, value interface{}) *MapNode {
  9.     if node == nil {
  10.         return &MapNode{key: key, value: value, height: 1}
  11.     }
  12.     if key < node.key {
  13.         node.left = insertMapNode(node.left, key, value)
  14.     } else if key > node.key {
  15.         node.right = insertMapNode(node.right, key, value)
  16.     } else {
  17.         node.value = value
  18.         return node
  19.     }

  20.     node.height = 1 + max(height(node.left), height(node.right))

  21.     balance := getBalance(node)

  22.     if balance > 1 && key < node.left.key {
  23.         return rightRotate(node)
  24.     }

  25.     if balance < -1 && key > node.right.key {
  26.         return leftRotate(node)
  27.     }

  28.     if balance > 1 && key > node.left.key {
  29.         node.left = leftRotate(node.left)
  30.         return rightRotate(node)
  31.     }

  32.     if balance < -1 && key < node.right.key {
  33.         node.right = rightRotate(node.right)
  34.         return leftRotate(node)
  35.     }

  36.     return node
  37. }
复制代码


1.3.2 set的实现

set是一种无重复元素的数据结构,可以通过AVL树或红黑树实现。每个节点存储一个元素,支持插入、删除和查找操作。

示例代码:

  1. type SetNode struct {
  2.     key    int
  3.     height int
  4.     left   *SetNode
  5.     right  *SetNode
  6. }

  7. func insertSetNode(node *SetNode, key int) *SetNode {
  8.     if node == nil {
  9.         return &SetNode{key: key, height: 1}
  10.     }
  11.     if key < node.key {
  12.         node.left = insertSetNode(node.left, key)
  13.     } else if key > node.key {
  14.         node.right = insertSetNode(node.right, key)
  15.     } else {
  16.         return node
  17.     }

  18.     node.height = 1 + max(height(node.left), height(node.right))

  19.     balance := getBalance(node)

  20.     if balance > 1 && key < node.left.key {
  21.         return rightRotate(node)
  22.     }

  23.     if balance < -1 && key > node.right.key {
  24.         return leftRotate(node)
  25.     }

  26.     if balance > 1 && key > node.left.key {
  27.         node.left = leftRotate(node.left)
  28.         return rightRotate(node)
  29.     }

  30.     if balance < -1 && key < node.right.key {
  31.         node.right = rightRotate(node.right)
  32.         return leftRotate(node)
  33.     }

  34.     return node
  35. }
复制代码


2. 结论

通过本文的介绍,我们了解了AVL树和红黑树的基本原理及实现方法,并讨论了如何将它们封装成map和set数据结构。掌握这些高级数据结构和算法对于提高程序性能和解决复杂问题至关重要。希望这篇文章能对你理解和使用平衡二叉搜索树有所帮助。






/ 荔枝学姐de课后专栏 /

Hi!这里是荔枝学姐~

欢迎来到我的课后专栏

自然语言学渣 NLP摆烂姐

热衷于技术写作 IT边角料

AIGC & Coding & linux ...

~互撩~ TG: @Shaw_0xyz

荔枝学姐爱吃荔枝!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系站长|Archiver|手机版|小黑屋|主机论坛

GMT+8, 2025-4-4 13:54 , Processed in 0.065082 second(s), 23 queries .

Powered by 主机论坛 HostSsss.Com

HostSsss.Com

快速回复 返回顶部 返回列表