项目介绍
这是一个基于Flask框架的游戏网站项目,包含多个小游戏(如猜数字、井字棋、记忆配对、贪吃蛇等),并使用红黑树(RBTree)数据结构实现了高效的排行榜系统。
项目特点:
使用Python Flask作为后端框架
每个游戏独立维护一个排行榜
使用红黑树数据结构存储和排序分数
支持分数提交和排行榜查询
排行榜限制最大容量(1000条记录),自动淘汰最低分
红黑树作为排行榜数据结构的优势:
高效的插入和查询操作(O(log n)时间复杂度)
自动维护数据有序性
平衡性好,避免极端情况下的性能退化
可以高效获取前N名高分玩家
手写红黑树实现游戏排行榜指南
红黑树基础概念
红黑树是一种自平衡的二叉查找树,具有以下性质:
每个节点是红色或黑色
根节点是黑色
每个叶子节点(NIL)是黑色
红色节点的子节点必须是黑色
从任一节点到其每个叶子的所有路径包含相同数目的黑色节点
实现步骤
-
定义节点类
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 # 父节点
-
实现红黑树基本结构
class RBTree:
def init (self):
self.nil = RBNode(None, None, BLACK) # 哨兵节点
self.root = self.nil # 初始时根节点指向哨兵
-
实现插入操作
插入分为两步:
普通二叉查找树插入
修复红黑树性质
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)
-
实现插入修复
插入后可能违反红黑树性质,需要通过旋转和重新着色修复:
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
-
实现旋转操作
旋转是维护红黑树平衡的关键操作:
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
- 实现排行榜功能
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名玩家
内存使用效率高
这种实现特别适合需要频繁更新和查询排行榜的游戏应用场景,能够保证在大数据量下依然保持良好的性能。