github-czy

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

项目介绍
这是一个基于Flask框架的游戏网站项目,包含多个小游戏(如猜数字、井字棋、记忆配对、贪吃蛇等),并使用红黑树(RBTree)数据结构实现了高效的排行榜系统。
项目特点:
使用Python Flask作为后端框架

每个游戏独立维护一个排行榜

使用红黑树数据结构存储和排序分数

支持分数提交和排行榜查询

排行榜限制最大容量(1000条记录),自动淘汰最低分

红黑树作为排行榜数据结构的优势:

高效的插入和查询操作(O(log n)时间复杂度)

自动维护数据有序性

平衡性好,避免极端情况下的性能退化

可以高效获取前N名高分玩家

手写红黑树实现游戏排行榜指南
红黑树基础概念
红黑树是一种自平衡的二叉查找树,具有以下性质:

每个节点是红色或黑色

根节点是黑色

每个叶子节点(NIL)是黑色

红色节点的子节点必须是黑色

从任一节点到其每个叶子的所有路径包含相同数目的黑色节点

实现步骤

  1. 定义节点类
    class RBNode:
    def init(self, key, value, color=RED):
    self.key = key # 排序键(分数)
    self.value = value # 存储的值(玩家名)
    self.color = color # 节点颜色
    self.left = None # 左子节点
    self.right = None # 右子节点
    self.parent = None # 父节点

  2. 实现红黑树基本结构
    class RBTree:
    def init(self):
    self.nil = RBNode(None, None, BLACK) # 哨兵节点
    self.root = self.nil # 初始时根节点指向哨兵

  3. 实现插入操作
    插入分为两步:
    普通二叉查找树插入
    修复红黑树性质
    def insert(self, key, value):

    创建新节点(默认为红色)

    new_node = RBNode(key, value)
    new_node.left = self.nil
    new_node.right = self.nil

    普通BST插入

    parent = None
    current = self.root
    while current != self.nil:
    parent = current
    if key < current.key:
    current = current.left
    else:
    current = current.right

    设置新节点的父节点

    new_node.parent = parent

    更新父节点的子节点引用

    if parent is None:
    self.root = new_node
    elif key < parent.key:
    parent.left = new_node
    else:
    parent.right = new_node

    修复红黑树性质

    self._fix_insert(new_node)

  4. 实现插入修复
    插入后可能违反红黑树性质,需要通过旋转和重新着色修复:
    def _fix_insert(self, node):
    while node.parent.color == RED:
    # 父节点是祖父的右子节点
    if node.parent == node.parent.parent.right:
    uncle = node.parent.parent.left
    if uncle.color == RED:
    # 情况1: 叔叔节点是红色
    uncle.color = BLACK
    node.parent.color = BLACK
    node.parent.parent.color = RED
    node = node.parent.parent
    else:
    if node == node.parent.left:
    # 情况2: 叔叔节点是黑色且当前节点是左子节点
    node = node.parent
    self._right_rotate(node)
    # 情况3: 叔叔节点是黑色且当前节点是右子节点
    node.parent.color = BLACK
    node.parent.parent.color = RED
    self._left_rotate(node.parent.parent)
    else:
    # 对称情况
    uncle = node.parent.parent.right
    if uncle.color == RED:
    uncle.color = BLACK
    node.parent.color = BLACK
    node.parent.parent.color = RED
    node = node.parent.parent
    else:
    if node == node.parent.right:
    node = node.parent
    self._left_rotate(node)
    node.parent.color = BLACK
    node.parent.parent.color = RED
    self._right_rotate(node.parent.parent)

     if node == self.root:
         break
    

    self.root.color = BLACK

  5. 实现旋转操作
    旋转是维护红黑树平衡的关键操作:
    def _left_rotate(self, x):
    y = x.right
    x.right = y.left
    if y.left != self.nil:
    y.left.parent = x

    y.parent = x.parent
    if x.parent is None:
    self.root = y
    elif x == x.parent.left:
    x.parent.left = y
    else:
    x.parent.right = y

    y.left = x
    x.parent = y

def _right_rotate(self, x):
y = x.left
x.left = y.right
if y.right != self.nil:
y.right.parent = x

y.parent = x.parent
if x.parent is None:
    self.root = y
elif x == x.parent.right:
    x.parent.right = y
else:
    x.parent.left = y

y.right = x
x.parent = y
  1. 实现排行榜功能
    def get_top_scores(self, n):
    """获取前n个最高分"""
    result = []
    self._reverse_inorder(self.root, result, n)
    return result

def _reverse_inorder(self, node, result, limit):
if node == self.nil or len(result) >= limit:
return

# 先遍历右子树(更大的值)
self._reverse_inorder(node.right, result, limit)

if len(result) < limit:
    result.append((node.key, node.value))

# 再遍历左子树(更小的值)
self._reverse_inorder(node.left, result, limit)

总结
通过手写红黑树实现游戏排行榜系统:
高效的分数插入和查询性能
自动维护分数排序
可以轻松获取前N名玩家
内存使用效率高
这种实现特别适合需要频繁更新和查询排行榜的游戏应用场景,能够保证在大数据量下依然保持良好的性能。

posted on 2025-04-15 19:48  github_czy  阅读(91)  评论(0)    收藏  举报